diff -Naur linux-2.6.25/drivers/misc/classes/char/gpio_char.c linux-2.6.25.ep93xx/drivers/misc/classes/char/gpio_char.c
--- linux-2.6.25/drivers/misc/classes/char/gpio_char.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/char/gpio_char.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,209 @@
+/**
+ * A character device interface to gpio devices. Part of the GPIO class.
+ * 
+ */
+
+/* TODO: analyze these includes to weed out any that are unnecessary */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/cdev.h>
+#include <linux/class/gpio.h>
+#include <linux/class/char/gpio_char.h>
+#include <asm/uaccess.h>
+
+static int gpio_major =    GPIO_MAJOR;
+static int gpio_minor =    0;
+static int gpio_num_devs = GPIO_MAX_DEVS;
+
+struct gpio_char_dev {
+    gpio_t *gpio;
+    struct cdev cdev;
+};
+
+//#define DEBUG_GC
+
+#ifdef DEBUG_GC
+#define DPRINTK(string, args...) printk("gpio_char: " string, ##args)
+#else
+#define DPRINTK(string, args...)
+#endif
+
+/* function prototypes */
+static int gpio_char_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg);
+static int gpio_char_open(struct inode *inode, struct file *file);
+static int gpio_char_release(struct inode *inode, struct file *file);
+static int gpio_char_setup_cdev(struct gpio_char_dev *dev);
+
+/* struct for fops declarations */
+static const struct file_operations gpio_char_fops =
+{ 
+    .ioctl   = gpio_char_ioctl, 
+    .open    = gpio_char_open,
+    .release = gpio_char_release,
+};
+
+static int gpio_char_open(struct inode *inode, struct file *file)
+{
+    struct gpio_char_dev *dev; /* device information */
+    DPRINTK("gpio_char_open\n");
+    /* TODO: This may or may not be necessary */
+    dev = container_of(inode->i_cdev, struct gpio_char_dev, cdev);
+    file->private_data = dev;
+    return 0;
+}
+
+static int gpio_char_release(struct inode *inode, struct file *file)
+{
+    DPRINTK("gpio_char_release\n");
+    /* nothing to do here */
+    return 0;
+}
+
+static int gpio_char_ioctl(struct inode *inode, struct file *file,
+        unsigned int cmd, unsigned long arg)
+{
+    struct gpio_char_dev *dev = container_of(inode->i_cdev, struct gpio_char_dev, cdev);
+    gpio_t *gpio = dev->gpio;
+    gpio_data kmem[1];
+    int ret;
+    
+    /* make sure that this command is indeed one of gpio_char's */
+    if (_IOC_TYPE(cmd) != CHAR_CLASS_GPIO)
+        return -ENOTTY;
+    
+    switch(cmd)
+    {
+    case DDRREAD:
+        DPRINTK("DDRREAD ioctl\n");
+        if (gpio->ddr_read)
+            kmem[0] = atomic_gpio_ddr_read(gpio);
+        else
+            return -EFAULT;
+        return (copy_to_user((void *)arg, kmem, sizeof(gpio_data)) == 0 ) ? 0 : -EFAULT;
+        break;
+    case DDRWRITE:
+        DPRINTK("DDRWRITE ioctl\n");
+        if (copy_from_user(kmem, (void *)arg, sizeof(gpio_data)) != 0)
+            return -EFAULT;
+        if (gpio->ddr_write)
+            atomic_gpio_ddr_write(gpio, kmem[0]);
+        else 
+            return -EFAULT;
+        return 0;
+        break;
+    case DATAREAD:
+        DPRINTK("DATAREAD ioctl\n");
+        if (gpio->data_read)
+            kmem[0] = atomic_gpio_data_read(gpio);
+        else
+            return -EFAULT;
+        return (copy_to_user((void *)arg, kmem, sizeof(gpio_data)) == 0 ) ? 0 : -EFAULT;
+        break;
+    case DATAWRITE:
+        DPRINTK("DATAWRITE ioctl\n");
+        if (copy_from_user(kmem, (void *)arg, sizeof(gpio_data)) != 0)
+            return -EFAULT;
+        if (gpio->data_write)
+            atomic_gpio_data_write(gpio, kmem[0]);
+        else {
+            DPRINTK("error: invalid data_write\n");
+            return -EFAULT;
+        }
+        return 0;
+        break;
+    case INDEXREAD:
+        DPRINTK("INDEXREAD ioctl\n");
+        if (gpio->index_read)
+            kmem[0] = atomic_gpio_index_read(gpio);
+        else
+            return -EFAULT;
+        return (copy_to_user((void *)arg, kmem, sizeof(gpio_data)) == 0 ) ? 0 : -EFAULT;
+        break;
+    case INDEXWRITE:
+        DPRINTK("INDEXWRITE ioctl\n");
+        if ((ret = copy_from_user(kmem, (void __user *)arg, sizeof(gpio_data))) != 0) {
+            DPRINTK("copy_from_user returned error: %d bytes not copied\n", ret);
+            return -EFAULT;
+        }
+        if (gpio->index_write)
+            atomic_gpio_index_write(gpio, kmem[0]);
+        else {
+            DPRINTK("invalid index_write command\n");
+            return -EFAULT;
+        }
+        return 0;
+        break;
+    default :
+        DPRINTK("ioctl: no such command\n");
+        return -ENOTTY;
+    } /* END switch(cmd) */
+    DPRINTK("Invalid state, broke out of switch\n");
+    return -EFAULT; /* Error, we should never reach here */    
+}
+
+/* initialize the character interface -- called by gpio class on init */
+
+int gpio_char_init(void)
+{
+    int result;
+    dev_t dev = 0;
+    DPRINTK("gpio_char_init\n");
+    /* dynamic and static character device allocation */
+    if (gpio_major) {
+        dev = MKDEV(gpio_major, gpio_minor);
+        result = register_chrdev_region(dev, gpio_num_devs, "gpio_char");
+    }
+    else {
+        result = alloc_chrdev_region(&dev, gpio_minor, 
+                gpio_num_devs, "gpio_char");
+        gpio_major = MAJOR(dev);
+    }
+    if (result < 0)
+        printk(KERN_WARNING "gpio_char: can't get major %d, err %d\n", gpio_major,result);
+    
+    return result;
+}
+
+/* registers the actual char device, called by create when invoked by gpio class */
+
+static int gpio_char_setup_cdev(struct gpio_char_dev *dev)
+{
+    static int index = 0;
+    int err, devno = MKDEV(gpio_major, gpio_minor + index);
+    
+    DPRINTK("gpio_char_setup_cdev\n");
+    
+    cdev_init(&dev->cdev, &gpio_char_fops);
+    dev->cdev.owner = THIS_MODULE; /* not sure if this is still valid */
+    dev->cdev.ops = &gpio_char_fops;
+    err = cdev_add(&dev->cdev, devno, 1);
+    if (err)
+        printk(KERN_NOTICE "gpio_char: Error %d adding gpio_char%d\n", err, index);
+    
+    index++;
+    return devno;
+}
+
+/* create and register a new char device */
+
+int gpio_char_create(struct gpio_s *gpio)
+{
+    struct gpio_char_dev *chardev = kmalloc(sizeof(struct gpio_char_dev),GFP_KERNEL);
+    DPRINTK("gpio_char_create\n");
+    if (!chardev) {
+        printk(KERN_NOTICE "Error allocating memory\n");
+        return -ENOMEM;
+    }
+    chardev->gpio = gpio;
+    
+    return gpio_char_setup_cdev(chardev);
+}
diff -Naur linux-2.6.25/drivers/misc/classes/char/Makefile linux-2.6.25.ep93xx/drivers/misc/classes/char/Makefile
--- linux-2.6.25/drivers/misc/classes/char/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/char/Makefile	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,6 @@
+#
+# Makefile for the misc char classes
+#
+
+obj-$(CONFIG_GPIOCLASS_CHAR)	+= gpio_char.o
+obj-$(CONFIG_SPICLASS_CHAR)		+= spi_char.o
\ No newline at end of file
diff -Naur linux-2.6.25/drivers/misc/classes/char/spi_char.c linux-2.6.25.ep93xx/drivers/misc/classes/char/spi_char.c
--- linux-2.6.25/drivers/misc/classes/char/spi_char.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/char/spi_char.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,225 @@
+/**
+ * A character device interface to spi devices. Part of the SPI class.
+ * 
+ */
+
+/* TODO: analyze these includes to weed out any that are unnecessary */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/cdev.h>
+#include <linux/class/spi.h>
+#include <linux/class/char/spi_char.h>
+#include <asm/uaccess.h>
+
+static int spi_major =    SPI_MAJOR;
+static int spi_minor =    0;
+static int spi_num_devs = SPI_MAX_DEVS;
+
+struct spi_char_dev {
+    spi_t *spi;
+    struct cdev cdev;
+};
+
+//#define DEBUG_SC
+
+#ifdef DEBUG_SC
+#define DPRINTK(string, args...) printk("spi_char: " string, ##args)
+#else
+#define DPRINTK(string, args...)
+#endif
+
+/* function prototypes */
+static int spi_char_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg);
+static int spi_char_open(struct inode *inode, struct file *file);
+static int spi_char_release(struct inode *inode, struct file *file);
+static int spi_char_setup_cdev(struct spi_char_dev *dev);
+
+/* struct for fops declarations */
+static const struct file_operations spi_char_fops =
+{ 
+    .ioctl   = spi_char_ioctl, 
+    .open    = spi_char_open,
+    .release = spi_char_release,
+};
+
+static int spi_char_open(struct inode *inode, struct file *file)
+{
+    struct spi_char_dev *dev; /* device information */
+    DPRINTK("spi_char_open\n");
+    /* TODO: This may or may not be necessary */
+    dev = container_of(inode->i_cdev, struct spi_char_dev, cdev);
+    file->private_data = dev;
+    return 0;
+}
+
+static int spi_char_release(struct inode *inode, struct file *file)
+{
+    DPRINTK("spi_char_release\n");
+    /* nothing to do here */
+    return 0;
+}
+
+static int spi_char_ioctl(struct inode *inode, struct file *file,
+        unsigned int cmd, unsigned long arg)
+{
+    struct spi_char_dev *dev = container_of(inode->i_cdev, struct spi_char_dev, cdev);
+    spi_t *spi = dev->spi;
+    spi_control kmem[1];
+    
+    /* make sure that this command is indeed one of spi_char's */
+    if (_IOC_TYPE(cmd) != CHAR_CLASS_SPI)
+        return -ENOTTY;
+    
+    switch(cmd)
+    {
+    case XMIT:{
+    	spi_transfer_t *t=NULL;
+    	spi_data *buf=NULL;
+    	int errval=0;
+        DPRINTK("XMIT ioctl\n");
+        if (!spi->xmit)return -EFAULT;//method not available
+	t = kmalloc(sizeof(spi_transfer_t), GFP_KERNEL);
+        if (copy_from_user(t, (void *)arg, sizeof(spi_transfer_t)) != 0){errval=-EFAULT;goto cleanup;}
+        if(t->size==0)return 0;//not an error, but nothing to do
+        if((t->miso)||(t->mosi))buf = kmalloc(t->size,GFP_KERNEL);
+        if(t->mosi)if (copy_from_user(buf, t->mosi, t->size) != 0){errval=-EFAULT;goto cleanup;}
+        if(atomic_spi_xmit(spi,t->mosi?buf:NULL,t->miso?buf:NULL,t->size)!=0){errval=-EFAULT;goto cleanup;}
+        if(t->miso)if(copy_to_user(t->miso, buf, t->size)!= 0 ){errval=-EFAULT;goto cleanup;}
+cleanup:
+        if(buf)kfree(buf);
+	if(t)kfree(t);
+        return errval;
+        break;
+    }
+    case CONFREAD:
+        DPRINTK("CONFREAD ioctl\n");
+        if (spi->confread)
+            kmem[0] = atomic_spi_conf_read(spi);
+        else
+            return -EFAULT;
+        return (copy_to_user((void *)arg, kmem, sizeof(spi_control)) == 0 ) ? 0 : -EFAULT;
+        break;
+    case CONFWRITE:
+        DPRINTK("CONFWRITE ioctl\n");
+        if (copy_from_user(kmem, (void *)arg, sizeof(spi_control)) != 0)
+            return -EFAULT;
+        if (spi->confwrite)
+            atomic_spi_conf_write(spi, kmem[0]);
+        else 
+            return -EFAULT;
+        return 0;
+        break;
+    case SPEEDREAD:
+        DPRINTK("SPEEDREAD ioctl\n");
+        if (spi->speedread)
+            kmem[0] = atomic_spi_speed_read(spi);
+        else
+            return -EFAULT;
+        return (copy_to_user((void *)arg, kmem, sizeof(spi_control)) == 0 ) ? 0 : -EFAULT;
+        break;
+    case SPEEDWRITE:
+        DPRINTK("SPEEDWRITE ioctl\n");
+        if (copy_from_user(kmem, (void *)arg, sizeof(spi_control)) != 0)
+            return -EFAULT;
+        if (spi->speedwrite)
+            atomic_spi_speed_write(spi, kmem[0]);
+        else {
+            DPRINTK("error: invalid speed write\n");
+            return -EFAULT;
+        }
+        return 0;
+        break;
+    case TIPREAD:
+        DPRINTK("TIPREAD ioctl\n");
+        if (spi->tip)
+            kmem[0] = atomic_spi_tip_read(spi);
+        else
+            return -EFAULT;
+        return (copy_to_user((void *)arg, kmem, sizeof(spi_control)) == 0 ) ? 0 : -EFAULT;
+        break;
+    case TIPWRITE:
+        DPRINTK("TIPWRITE ioctl\n");
+        if (copy_from_user(kmem, (void *)arg, sizeof(spi_control)) != 0)
+            return -EFAULT;
+        if (spi->tip)
+            atomic_spi_tip_write(spi, kmem[0]);
+        else {
+            DPRINTK("error: invalid speed write\n");
+            return -EFAULT;
+        }
+        return 0;
+        break;
+    default :
+        DPRINTK("ioctl: no such command\n");
+        return -ENOTTY;
+    } /* END switch(cmd) */
+    DPRINTK("Invalid state, broke out of switch\n");
+    return -EFAULT; /* Error, we should never reach here */    
+}
+
+/* initialize the character interface -- called by spi class on init */
+
+int spi_char_init(void)
+{
+    int result;
+    dev_t dev = 0;
+    DPRINTK("spi_char_init\n");
+    /* dynamic and static character device allocation */
+    if (spi_major) {
+        dev = MKDEV(spi_major, spi_minor);
+        result = register_chrdev_region(dev, spi_num_devs, "spi_char");
+    }
+    else {
+        result = alloc_chrdev_region(&dev, spi_minor, 
+                spi_num_devs, "spi_char");
+        spi_major = MAJOR(dev);
+    }
+    if (result < 0)
+        printk(KERN_WARNING "spi_char: can't get major %d, err %d\n", spi_major,result);
+    
+    return result;
+}
+
+/* registers the actual char device, called by create when invoked by spi class */
+
+static int spi_char_setup_cdev(struct spi_char_dev *dev)
+{
+    static int index = 0;
+    int err, devno = MKDEV(spi_major, spi_minor + index);
+    
+    DPRINTK("spi_char_setup_cdev\n");
+    
+    cdev_init(&dev->cdev, &spi_char_fops);
+    dev->cdev.owner = THIS_MODULE; /* not sure if this is still valid */
+    dev->cdev.ops = &spi_char_fops;
+    err = cdev_add(&dev->cdev, devno, 1);
+    if (err)
+        printk(KERN_NOTICE "spi_char: Error %d adding spi_char%d\n", err, index);
+    
+    index++;
+    return devno;
+}
+
+/* create and register a new char device */
+
+int spi_char_create(struct spi_s *spi)
+{
+    struct spi_char_dev *chardev = kmalloc(sizeof(struct spi_char_dev),GFP_KERNEL);
+    DPRINTK("spi_char_create\n");
+    if (!chardev) {
+        printk(KERN_NOTICE "Error allocating memory\n");
+        return -ENOMEM;
+    }
+    chardev->spi = spi;
+    
+    return spi_char_setup_cdev(chardev);
+}
diff -Naur linux-2.6.25/drivers/misc/classes/gpio.c linux-2.6.25.ep93xx/drivers/misc/classes/gpio.c
--- linux-2.6.25/drivers/misc/classes/gpio.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/gpio.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,179 @@
+/**
+ * A class for simple gpio ports
+ * Several types of general purpose devices are available 
+ * which all export the same basic functionity 
+ * through different underlying methods
+ * This class can also be used to export simple interfaces
+ * to an 8 bit port into user space
+ */
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include <linux/kdev_t.h>
+#include <linux/chelper.h>
+#include <linux/class/gpio.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_GPIOCLASS_RTDM
+#include <rtdm/rtdm_driver.h>
+#include <linux/class/rtdm/gpio_rtdm.h>
+#define ATOMIC(a) RTDM_EXECUTE_ATOMICALLY(a)
+#else
+#define ATOMIC(a) a
+#endif //CONFIG_GPIOCLASS_RTDM
+
+#ifdef CONFIG_GPIOCLASS_CHAR
+#include <linux/class/char/gpio_char.h>
+#endif
+
+/************************************************************
+ * the global device class
+ */
+static struct class *gpioclass = NULL;
+
+struct class *gpio_declare(void){
+	if(!gpioclass){
+		printk("registering GPIO class\n");
+		gpioclass=class_create(THIS_MODULE,"gpio");
+#ifdef CONFIG_GPIOCLASS_CHAR
+		gpio_char_init();
+#endif
+	}
+	return gpioclass;
+}
+
+/***************************************************************************
+ * typical low level methods for accessing 8 bit ports
+ */
+ 
+int  gpio_ddr_write8(gpio_t *gpio, gpio_data data){iowrite8(data,gpio->ddr+gpio->index);return 0;}
+
+int  gpio_data_write8(gpio_t *gpio, gpio_data data){iowrite8(data,gpio->data+gpio->index);gpio->shadow=data;return 0;}
+
+int  gpio_index_write(gpio_t *gpio, gpio_data data){data = (data>gpio->range)?gpio->range:data;gpio->index = data;return 0;}
+
+int  gpio_empty_write(gpio_t *gpio, gpio_data data){return 0;}
+
+gpio_data gpio_ddr_read8(gpio_t *gpio){return ioread8(gpio->ddr+gpio->index);}
+
+gpio_data gpio_data_read8(gpio_t *gpio){return ioread8(gpio->data+gpio->index);}
+
+gpio_data gpio_index_read(gpio_t *gpio){return gpio->index;}
+
+gpio_data gpio_shadow_read8(gpio_t *gpio){return gpio->shadow;}
+	
+gpio_data gpio_ff_read(gpio_t *gpio){return 0xff;}
+	
+gpio_data gpio_zero_read(gpio_t *gpio){return 0;}
+
+/***************************************************************************
+ * Atomic method wrappers
+ */
+int atomic_gpio_ddr_write(gpio_t *gpio,gpio_data data){
+	ATOMIC(gpio->ddr_write(gpio,data);)
+	return 0;
+}
+	
+gpio_data atomic_gpio_ddr_read(gpio_t *gpio){
+	gpio_data retval;
+	ATOMIC(retval = gpio->ddr_read(gpio);)
+	return retval;
+}
+
+int atomic_gpio_data_write(gpio_t *gpio,gpio_data data){
+	ATOMIC(gpio->data_write(gpio,data);)
+	return 0;
+}
+	
+gpio_data atomic_gpio_data_read(gpio_t *gpio){
+	gpio_data retval;
+	ATOMIC(retval = gpio->data_read(gpio);)
+	return retval;
+}
+
+int atomic_gpio_index_write(gpio_t *gpio,gpio_data data){
+	ATOMIC(gpio->index_write(gpio,data);)
+	return 0;
+}
+	
+gpio_data atomic_gpio_index_read(gpio_t *gpio){
+	gpio_data retval;
+	ATOMIC(retval = gpio->index_read(gpio);)
+	return retval;
+}
+
+/***************************************************************************
+ * gpio sysfs operations
+ */
+#ifdef CONFIG_GPIOCLASS_SYSFS
+static ssize_t gpio_data_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	gpio_t *gpio = cls->class_data;
+	gpio_data data = sfs_getint(buf,count,&size);
+	atomic_gpio_data_write(gpio, data);
+	return size;
+}
+
+static ssize_t gpio_ddr_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	gpio_t *gpio = cls->class_data;
+	gpio_data data = sfs_getint(buf,count,&size);
+	atomic_gpio_ddr_write(gpio, data);
+	return size;
+}
+
+static ssize_t gpio_index_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	gpio_t *gpio = cls->class_data;
+	gpio_data data = sfs_getint(buf,count,&size);
+	atomic_gpio_index_write(gpio, data);
+	return size;
+}
+
+static ssize_t gpio_data_show(struct class_device *cls, char *buf){
+	gpio_t *gpio = cls->class_data;
+	return sprintf(buf,"%x\r\n",atomic_gpio_data_read(gpio));
+}
+
+static ssize_t gpio_ddr_show(struct class_device *cls, char *buf){
+	gpio_t *gpio = cls->class_data;
+	return sprintf(buf,"%x\r\n",atomic_gpio_ddr_read(gpio));
+}
+
+static ssize_t gpio_index_show(struct class_device *cls, char *buf){
+	gpio_t *gpio = cls->class_data;
+	return sprintf(buf,"%x\r\n",atomic_gpio_index_read(gpio));
+}
+
+static CLASS_DEVICE_ATTR(ddr,S_IRUGO|S_IWUGO,gpio_ddr_show,gpio_ddr_store);
+static CLASS_DEVICE_ATTR(data,S_IRUGO|S_IWUGO,gpio_data_show,gpio_data_store);
+static CLASS_DEVICE_ATTR(index,S_IRUGO|S_IWUGO,gpio_index_show,gpio_index_store);
+#endif //CONFIG_GPIOCLASS_SYSFS
+/***************************************************************************
+* class instantiation
+*/
+struct class_device *gpio_register_class_device(gpio_t *gpio){		
+struct class *gpio_master = gpio_declare();
+struct class_device *dev;	
+dev_t devnum = MKDEV(0, 0);
+
+#ifdef CONFIG_GPIOCLASS_CHAR
+devnum = gpio_char_create(gpio);
+#endif	
+	
+dev = class_device_create(gpio_master, NULL, devnum, NULL, gpio->name);
+dev->class_data = gpio;	
+
+#ifdef CONFIG_GPIOCLASS_SYSFS
+	if((gpio->ddr_write)&&(gpio->ddr_read))class_device_create_file(dev,&class_device_attr_ddr);
+	if((gpio->data_write)&&(gpio->data_read))class_device_create_file(dev,&class_device_attr_data);
+	if((gpio->index_write)&&(gpio->index_read))class_device_create_file(dev,&class_device_attr_index);
+#endif	 
+
+#ifdef CONFIG_GPIOCLASS_RTDM
+	rt_gpio_device_create(gpio);
+#endif
+
+return dev;			
+}
diff -Naur linux-2.6.25/drivers/misc/classes/Kconfig linux-2.6.25.ep93xx/drivers/misc/classes/Kconfig
--- linux-2.6.25/drivers/misc/classes/Kconfig	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/Kconfig	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,94 @@
+#
+# Input device configuration
+#
+
+menu "misc device classes"
+
+config GPIOCLASS
+        bool "GPIO class"
+        ---help---
+	  This is a set of classes for general purpose io ports.
+	  These devices typically contain a data register, 
+	  which holds the current state of the pins, and a ddr register, 
+	  which sets the pin to input or output, 0 or 1 respectively 
+
+config GPIOCLASS_SYSFS
+		depends on SYSFS && GPIOCLASS
+        bool "sysfs interface"
+        ---help---
+	  enables a sysfs interface to the gpio class
+
+config GPIOCLASS_RTDM 
+		depends on XENO_SKIN_RTDM && GPIOCLASS
+        bool "rtdm interface"
+        ---help---
+	  enables a Xenomai RTDM interface to the gpio class
+	  
+config GPIOCLASS_CHAR
+		depends on GPIOCLASS
+		bool "char interface"
+		---help---
+		Enables a character device interface to the GPIO class.
+
+config PWMCLASS
+        bool "PWM class"
+        ---help---
+	  This is a set of classes for pulse width modulation.
+	  It allows the creation of pwm classes which can be configured
+	  through sysfs. PWM devices typically contain a 
+	  duty and frequency configuration register.
+	  
+config PWMCLASS_SYSFS
+		depends on SYSFS && PWMCLASS
+        bool "sysfs interface"
+        ---help---
+	  enables a sysfs interface to the pwm class
+
+config PWMCLASS_RTDM 
+		depends on XENO_SKIN_RTDM && PWMCLASS
+        bool "rtdm interface"
+        ---help---
+	  enables a Xenomai RTDM interface to the pwm class	  
+	  
+config MMCCLASS
+        bool "SPI/MMC class based driver"
+        ---help---
+        A MMC/SD class for transferring MMC information to a block driver layer.
+        Designed for providing board specific syncronizations 
+        between periodic spi devices and mmc block devices.
+        This class allows the mach to orchistrate low level spi interactions.   
+        
+config SPICLASS
+        bool "SPI class"
+        ---help---
+	  This is a set of classes for SPI interfaces.
+	  It allows the creation of spi classes which can be configured
+	  through sysfs.SPI devices typically contain a 
+	  speed and flags register, a method for locking the bus, 
+	  and a bidirectional "xmit" method     
+
+config SPICLASS_SYSFS
+	depends on SYSFS && SPICLASS
+	bool "sysfs interface"
+	---help---
+	Enables a sysfs interface to the spi class
+
+config SPICLASS_CHAR
+	depends on SPICLASS
+	bool "char interface"
+	---help---
+	Enables a character device interface to the spi class.
+        
+config LSI2ESC
+        depends on SPICLASS
+        bool "Linux SPI Interface to EMAC SPI Class interface"
+        ---help---
+        Enables a generic interface between the Linux SPI
+        driver and the EMAC SPI Class. Boards with an SPI controller
+        driver can use this to define generic access to a device
+        through the EMAC SPI class.
+
+ endmenu
+
+
+
diff -Naur linux-2.6.25/drivers/misc/classes/Makefile linux-2.6.25.ep93xx/drivers/misc/classes/Makefile
--- linux-2.6.25/drivers/misc/classes/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/Makefile	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,13 @@
+#
+# Makefile for the misc classes
+#
+
+EXTRA_CFLAGS += -Iinclude/xenomai
+obj-$(CONFIG_GPIOCLASS)		+= gpio.o
+obj-$(CONFIG_PWMCLASS)		+= pwm.o
+obj-$(CONFIG_MMCCLASS)		+= mmc.o
+obj-$(CONFIG_SPICLASS)		+= spi.o
+obj-$(CONFIG_LSI2ESC)       += spi_interface.o
+mmc-y := mmcprot.o mmcblock.o
+obj-y += rtdm/
+obj-y += char/
diff -Naur linux-2.6.25/drivers/misc/classes/mmcblock.c linux-2.6.25.ep93xx/drivers/misc/classes/mmcblock.c
--- linux-2.6.25/drivers/misc/classes/mmcblock.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/mmcblock.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,272 @@
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>	
+#include <linux/slab.h>		
+#include <linux/fs.h>		
+#include <linux/errno.h>	
+#include <linux/types.h>	
+#include <linux/fcntl.h>	
+#include <linux/hdreg.h>	
+#include <linux/genhd.h>
+#include <linux/blkdev.h>
+#include <linux/buffer_head.h>	
+#include <linux/bio.h>
+#include <linux/timer.h>
+
+#include <linux/class/mmcprot.h>
+#include <linux/class/mmcblock.h>
+
+/***************************************************************************
+ * External Functions from mcf_mmc_prot
+ ***************************************************************************/
+#define DEVICE_NAME "mmc"
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+#define MAJOR_NR 121
+
+/*
+ * We can tweak our hardware sector size, but the kernel talks to us
+ * in terms of small sectors, always.
+ */
+#define KERNEL_SECTOR_SIZE	512
+
+MODULE_AUTHOR("N.Z. Gustavson <ngustavson@emacinc.com");
+MODULE_DESCRIPTION("Driver for MMC/SD Cards");
+
+#define MMC_MINORS 16
+
+/**
+ * Block transfer implementation for the mmc/sd 
+ * This is the base hardware transfer function for all block driver calls.
+ */
+static inline int mmctransfer(mmcslot_t *s, unsigned long sector,
+		unsigned long nsect, char *buffer, int write){
+			
+	unsigned long offset = sector;
+	unsigned long nbytes = nsect*KERNEL_SECTOR_SIZE;		
+	unsigned long blocks = nbytes/s->card.blocklength;
+
+	//SDHC use block addressing, 1.01's use byte addressing
+	if(!s->card.sdhc)offset*=KERNEL_SECTOR_SIZE;
+	
+	MMCBDEBUG("mmc transfer\n");
+	MMCBDEBUG("mmc sector %lu\n",sector);
+	MMCBDEBUG("mmc nsect %lu\n",nsect);
+	MMCBDEBUG("mmc nbytes %lu\n",nbytes);
+    MMCBDEBUG("s->card.blocklength %u\n",s->card.blocklength);
+	
+	if ((offset + nbytes) > s->card.size) {
+		printk ("Beyond-end write (%ld %ld)\n", offset, nbytes);
+		return -1;
+	}
+	
+	if (blocks==0) {
+		printk ("Device blocklength>%u not supported\n",KERNEL_SECTOR_SIZE);
+		return -1;
+	}
+		
+	if (write)
+		return(WRITE_MULTIPLE_BLOCK(s,offset, buffer, s->card.blocklength, blocks));
+	else
+		return(READ_MULTIPLE_BLOCK(s,offset,buffer,s->card.blocklength,blocks));	
+}
+
+/**
+ * request implementation
+ */
+void mmc_request(request_queue_t *q){
+		
+	struct request *req;		
+	MMCBDEBUG("mmc_request\n"); 
+	
+		while ((req = elv_next_request(q)) != NULL) {
+			mmcslot_t *s = req->rq_disk->private_data;				
+				
+		if (!(s->state&READY)){
+			printk("Device is not currently valid\n");
+			end_request(req, 0);
+			continue;
+		}
+		
+		if (!blk_fs_request(req)) {
+			MMCBDEBUG (KERN_NOTICE "Skip non-fs request\n");
+			end_request(req, 0);
+			continue;
+		}
+					
+			if((mmctransfer(s, req->sector, req->current_nr_sectors,
+					req->buffer, rq_data_dir(req)))<0){
+				MMCBDEBUG ("transfer failed\n");							
+				end_request(req,0);//failure				
+				}
+			else{
+				MMCBDEBUG ("transfer success\n");
+				end_request(req,1);	//success	
+			}			
+		}	
+	MMCBDEBUG("mmc_request end\n");
+	}
+
+
+/******************************************************************************
+ * Removable media support
+ ******************************************************************************/
+static int mmc_check_media_change(struct gendisk *gd){
+mmcslot_t *s = gd->private_data;
+return(s->state&CHANGED ? 1:0);		
+}
+
+static int mmc_revalidate(struct gendisk *gd){
+mmcslot_t *s = gd->private_data;
+if (s->state==(CHANGED|VALID)){
+	int err;
+	printk("MMC media change detected, reinitializing\n");
+	if((err=mmcinit(s))<0){
+		printk("failed to initialize card\n");
+		s->state = INVALID;
+		return err;
+	}
+	set_capacity(gd, s->card.sectors*(s->card.blocklength/KERNEL_SECTOR_SIZE));
+	MMCBDEBUG("set capacity to %u\n",s->card.sectors*(s->card.blocklength/KERNEL_SECTOR_SIZE));
+	MMCBDEBUG("sectors=%u\n",s->card.sectors);
+	MMCBDEBUG("CSIZE=%u\n",s->card.CSD.C_SIZE);
+	MMCBDEBUG("CMULT=%u\n",s->card.CSD.C_SIZE_MULT);
+	s->state = VALID|READY;	
+}
+return -ENODEV;
+}
+
+/******************************************************************************
+ * Standard block driver file operations
+ ******************************************************************************/
+/**
+ * block device open 
+ */
+static int mmc_open(struct inode *inode, struct file *filp){
+	mmcslot_t *s = inode->i_bdev->bd_disk->private_data;
+	//struct gendisk *gd = s->private_data;	
+	
+	MMCBDEBUG("mmc_open\n"); 
+	
+	filp->private_data = s;
+	checkmedia_stop(s);
+	spin_lock(&s->lock); 
+	check_disk_change(inode->i_bdev);
+	if (!(s->state&READY)){
+			printk ("%s device not ready\n",s->name);
+			spin_unlock(&s->lock);
+			if(!s->users)checkmedia_start(s);//if no users remain, begin checking for media change again.
+			return -ENODEV;
+		}
+		
+	s->users++;
+	spin_unlock(&s->lock);		
+	return 0;
+}
+
+static int mmc_release(struct inode *inode, struct file *filp)
+{
+	mmcslot_t *s = inode->i_bdev->bd_disk->private_data;
+	MMCBDEBUG("mmc_release - getting lock\n"); 
+	spin_lock(&s->lock);
+	MMCBDEBUG("obtained lock\n"); 
+	s->users--;
+	if(!s->users)checkmedia_start(s);//if no users remain, begin checking for media change again.
+	spin_unlock(&s->lock);
+	MMCBDEBUG("released lock\n"); 
+	return 0;
+}
+
+static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct hd_geometry geometry;
+	//mmcslot_t *s = filp->private_data;
+	struct block_device *bdev = inode->i_bdev;
+	mmcslot_t *s = inode->i_bdev->bd_disk->private_data;
+	
+	if(!bdev){MMCBDEBUG("block device doesn't exist\n");return -EINVAL;}
+	if(!s){MMCBDEBUG("mmcslot doesn't exist\n");return -EINVAL;}
+	
+	MMCBDEBUG("mmc_ioctl\n"); 
+	
+	if (!(s->state&READY)){
+			printk ("Device is not currently valid\n");
+			return -ENODEV;
+		}
+	
+	if (cmd == BLKGETSIZE)
+	{
+		MMCBDEBUG("   BLKGETSIZE\n");
+		if (!arg) return -EINVAL;
+		if (copy_to_user((long *) arg, (long *) &s->card.blocklength, sizeof(s->card.blocklength))) return -EFAULT;
+		return 0;
+	}
+	else if (cmd == HDIO_GETGEO)
+	{
+		MMCBDEBUG("   HDIO_GETGEO\n");
+		if (!arg) return -EINVAL;
+		
+		geometry.cylinders	= get_capacity(bdev->bd_disk) / (4 * 16);
+		geometry.heads	= 4;
+		geometry.sectors	= 16;
+		geometry.start	= get_start_sect(bdev);
+		
+		if (copy_to_user((void *) arg, &geometry, sizeof(geometry))) return -EFAULT;
+		return 0;
+	}
+	else return -ENOTTY; /* unknown command */
+}
+
+static struct block_device_operations mmc_bdops = {
+	.owner           		= THIS_MODULE,
+	.open						=  mmc_open,
+	.release					=  mmc_release,
+	.ioctl 						=  mmc_ioctl,
+	.media_changed	= mmc_check_media_change,
+	.revalidate_disk	= mmc_revalidate,
+};
+/******************************************************************************
+ * driver initializations
+ ******************************************************************************/
+
+int mmc_diskize(mmcslot_t *s){
+	struct gendisk *gd = alloc_disk(MMC_MINORS);		
+	
+	MMCBDEBUG("setup device %s\n",s->name);	
+			 
+	gd->private_data =  s;
+	gd->major = MAJOR_NR;
+	gd->first_minor = s->slotnumber*MMC_MINORS;
+	gd->fops = &mmc_bdops;
+	gd->flags = GENHD_FL_REMOVABLE;
+	
+	if((gd->queue=blk_init_queue(mmc_request,&s->lock))==NULL){
+		printk("couldn't init block queue\n");
+		return -1;
+	}
+			
+	blk_queue_hardsect_size(gd->queue,s->card.blocklength);
+	gd->queue->queuedata = s;
+	snprintf (gd->disk_name, 32, s->name);
+
+	s->disk = gd;
+
+	add_disk(gd); 
+		
+	return 0;
+}
+
+int mmc_bdriver_init(void)
+{
+	register_blkdev(MAJOR_NR, DEVICE_NAME);
+	MMCBDEBUG("mmc block driver registered\n");
+	return 0;
+}
+
+void mmc_bdriver_exit(void)
+{
+	MMCBDEBUG("mmc block driver removed\n");	
+}
diff -Naur linux-2.6.25/drivers/misc/classes/mmcprot.c linux-2.6.25.ep93xx/drivers/misc/classes/mmcprot.c
--- linux-2.6.25/drivers/misc/classes/mmcprot.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/mmcprot.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,661 @@
+#define EXPORT_SYMTAB
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/class/mmcprot.h>
+#include <linux/class/mmcblock.h>
+
+#define DRV_MODULE_NAME 	"mmc"
+#define DRV_MODULE_VERSION 	"1.0"
+
+//#define MMCHARDERROR
+#ifdef MMCHARDERROR
+//debugging error, hard lock to find signal error via scope
+#define MMCERROR(err)	{printk("%s:MMCERR %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); while (1);}
+#else
+//return an error value on invalid communication.
+#define MMCERROR(err)	{return -err;}
+#endif
+
+
+static void checkmedia(unsigned long ptr){
+	mmcslot_t *s  = (mmcslot_t *)ptr;
+	//MMCDEBUG("checking media\n");
+	
+	if(!s->carddetect){s->state = INVALID;return;}//if cardetect is not implemented just return.
+	{
+	mmcslot_t *s = (mmcslot_t *)ptr;
+	int state = (s->carddetect(s))?VALID:INVALID;
+	if(state!=(s->state&VALID)){//state change
+  		printk("Multimedia card %s\n",state==VALID ? "inserted":"removed");	
+  		s->state = state|CHANGED;				  			
+	}
+	mod_timer(&s->timer,jiffies + HZ);//reset to probe next scheduler period	
+	}
+}
+
+
+void checkmedia_start(mmcslot_t *s){
+	setup_timer(&s->timer,checkmedia,(unsigned long)s);//make sure timer is initialized
+	checkmedia((unsigned long)s);//check immediately and reschedule
+}
+
+void checkmedia_stop(mmcslot_t *s){
+	del_timer_sync(&s->timer);//turn off the media check
+}
+
+
+
+static int mmcprot_probe(struct platform_device *pdev){	
+	if (pdev == NULL){MMCDEBUG("no platform device found\n");return -ENODEV;}
+	
+	{
+		mmcslot_t *s = pdev->dev.platform_data;
+		mmc_bdriver_init();//initialize block driver layer.
+		spin_lock_init(&s->lock);
+		s->card.blocklength = 512;//this could theoretically change dynamically, although in practice all cards use 512	
+		
+		MMCDEBUG("setting up timer\n");
+		checkmedia_start(s);
+		mmc_diskize(s);//setup a disk based upon this platform device.
+	}
+	
+	return 0;
+}
+
+//driver currently has no removal method.
+static struct platform_driver mmcprot_driver = {
+	.probe		= mmcprot_probe,
+	.driver		= {
+		.name	= "mmc",
+	},
+};
+
+static int __init mmcprot_init_module(void)
+{
+	printk(KERN_INFO DRV_MODULE_NAME " version " DRV_MODULE_VERSION " loading\n");
+	return platform_driver_register(&mmcprot_driver);
+}
+
+static void __exit mmcprot_cleanup_module(void)
+{
+	platform_driver_unregister(&mmcprot_driver);
+}
+
+module_init(mmcprot_init_module);
+module_exit(mmcprot_cleanup_module);
+
+/**********************************************************************************
+ * MMC transfer protocols
+ */
+
+/**
+	 * Fake CRC7. Currently the CRC is unused so
+	 * hard coded to 0x95 for the first
+	 * this was changed to a static variable to allow a second valid hard coded crc
+	 * to support the SDHC spec.
+	 * CRC value
+	 * @param array array to calculate the CRC7 on
+	 * @return
+	 */
+static int crcval;
+static int CRC7(u8 *array){
+		return crcval;
+		}
+
+/**
+	 * MMC packet building function
+	 * This function builds the command, clears and clears the remaining
+	 * frame which will be filled by the xmit function.
+	 * @param frame an array object to packetize
+	 * @param framelen size of the frame
+	 * @param command command index number
+	 * @param arg1 first arguement, high bits 31:16
+	 * @param arg2 second arguement, low bits 15:0
+	 * @param response number of response bits expected
+	 * @return 0
+	 */
+static int packetize(u8 *frame, int framelen, int command, int arg1, int arg2){
+		int START_BIT = 0;//MSB is zero
+		int TRANSMISSION_BIT = 0x40;
+		int STOP_BIT = 0x01;				
+		int bytenum;
+		
+		MMCDEBUG("packetize\n");
+		
+		frame[0] = (u8)((command|START_BIT|TRANSMISSION_BIT)&(0xff));
+		frame[1] = (u8)((arg1>>8)&(0xff));
+		frame[2] = (u8)((arg1)&(0xff));
+		frame[3] = (u8)((arg2>>8)&(0xff));
+		frame[4] = (u8)((arg2)&(0xff));
+		frame[5] = (u8)(CRC7(frame)|STOP_BIT);
+		
+		for(bytenum=COMMAND_LENGTH;bytenum<framelen;bytenum++)frame[bytenum] = (u8)0xff;
+	
+		return 0;
+	}
+
+/**
+	 * move the received response into int format
+	 * @param Rnum 1,2 or 5 number of bytes received
+	 * @param frame packet frame array
+	 * @param bytestart index of the Rx data in the frame
+	 * @return The response in u32 format
+	 */
+static u32 get_response(int Rnum, char *frame, int bytestart){
+		u32 Rx = frame[bytestart];
+		
+		MMCDEBUG("get_response Rnum = %x bytestart=%x\n",Rnum, bytestart);
+		
+		switch(Rnum){
+		case 1://standard command/response
+			//do nothing data already read
+		break;
+		case 2://two byte response
+			Rx<<=8;
+			Rx|=frame[bytestart+1];
+		break;
+		case 7:
+		case 5:// five byte response,READ_OCR and SEND_IF_COND use this.			
+			//CommandResponse(Rx);//command response check for print statements
+			Rx = frame[bytestart+1];
+			Rx<<=8;
+			Rx |= frame[bytestart+2];
+			Rx<<=8;
+			Rx |= frame[bytestart+3];
+			Rx<<=8;
+			Rx |= frame[bytestart+4];
+		break;	
+			}
+		return Rx;
+	}	
+
+/**
+ * Wait functions, read a short burst of data, then if nothing has arrived yet, sleep for
+ * a clock tick and try again with an eventual timeout.
+ */	
+	
+	/**
+	 * wait until the MMC returns a non-zero result
+	 * assumes pre-existing tip
+	 * @return 1
+	 */
+#define POLLNUMBER 100	 
+	 
+static int busy_wait(mmcslot_t *s){
+		int tickloop;
+		int shortloop;
+		u8 status=0;
+		
+		s->exchange(s,NULL, &status, 1);
+			
+		for(tickloop=0;tickloop<100;tickloop++){
+			for(shortloop=0;shortloop<POLLNUMBER;shortloop++){
+				s->exchange(s,NULL, &status, 1);	
+				if(status==0xff){
+					s->exchange(s,NULL, &status, 1);	;
+					return 1;//success
+				}						
+			}
+		set_current_state(TASK_INTERRUPTIBLE);//may want to shorten this.
+	 	schedule_timeout(HZ/100 ? HZ/100 : 1);
+		}
+			MMCERROR(1);//error
+	}
+
+/**
+ * delay loop that waits for an Rxtoken
+ * assumes pre-existing tip
+ * @return 1 if successful
+ */	
+ 
+static int wait_for_Rxtoken(mmcslot_t *s) {
+	u8 status=0;
+	int BR_START_TOKEN = 0xFE;//MMC token for data start
+	int tickloop;
+	int shortloop;
+		
+	for(tickloop=0;tickloop<100;tickloop++){
+	 	for(shortloop=0;shortloop<POLLNUMBER;shortloop++){	 		
+			s->exchange(s,NULL, &status, 1);
+			if(status==(u8)BR_START_TOKEN)
+				return 1;
+			}
+	 	set_current_state(TASK_INTERRUPTIBLE);
+	 	schedule_timeout(HZ/100 ? HZ/100 : 1);
+	 	}
+		MMCERROR(1);
+		
+		return 1;
+}
+
+
+/**
+	 * interprete the command response and throw exceptions as appropriate
+	 * @param response the byte containing the response
+	 * @return 0 if nothing is wrong
+	 */
+	static int CommandResponse(int response){				
+		if(response==0){
+			MMCDEBUG("command successful\n");
+			return 0;//no problems command succeeded
+		}
+		
+		printk("command error\n");
+		
+		if((response&MMCCOM_IDLE)!=0)
+			printk("idle\n");
+		if((response&MMCCOM_ERASE_RES)!=0)
+			printk("erase reset\n");
+		if((response&MMCCOM_ILLEGAL)!=0)
+			printk("illegal\n");
+		if((response&MMCCOM_CRC)!=0)
+			printk("crc\n");
+		if((response&MMCCOM_ERASE_SEQ)!=0)
+			printk("erase sequence\n");		
+		if((response&MMCCOM_ADDRESS)!=0)
+			printk("address\n");
+		if((response&MMCCOM_PARAMETER)!=0)
+			printk("parameter\n");
+		
+		MMCERROR(1);				
+	}
+/**
+ * interprete the data response and throw exceptions as appropriate
+ * @param response the byte containing the response
+ * @return 0 if nothing is wrong
+ */
+ 	static int DataResponse(int response){
+		//System.out.println("response="+response);
+		
+		switch(response&MMCDAT_D_RESPONSE_MASK){
+		case MMCDAT_DATA_ACC:
+			//System.out.println("Data accepted");
+			return 0;//data was accepted, no need to complain
+		case MMCDAT_CRC_ERR:
+			printk("CRC error\n");
+			MMCERROR(1);
+		case MMCDAT_WRITE_ERR:
+			printk("Write error\n");
+			MMCERROR(1);
+		default:
+			printk("Communications error\n");
+			MMCERROR(1);
+		}
+		
+		MMCERROR(1);
+	}	
+
+/**
+	 * General purpose method for tranceiving a command/response
+	 * to the MMC
+	 * @param command command index, see table below
+	 * @param arg1 first arguement, high bits 31:16
+	 * @param arg2 second arguement, low bits 15:0
+	 * @param blocking block before returning?
+	 * @param response number of response bits expected
+	 * @return the command response
+	 */
+int mmctransaction(mmcslot_t *s, int command, int arg1, int arg2,int blocking,int response){ 
+		int Rx;
+		int bytenum;
+		int framelen = COMMAND_LENGTH+Ncr_MAX+response;		
+		unsigned char readbuff[COMMAND_LENGTH+Ncr_MAX+MAX_RESPONSE];				
+		unsigned char writebuff[COMMAND_LENGTH+Ncr_MAX+MAX_RESPONSE];	
+						
+		packetize(writebuff,(COMMAND_LENGTH+Ncr_MAX+response),command,arg1,arg2);
+		
+		if((s->tip(s,TRUE))<0)MMCERROR(1);//could not obtain the bus
+			
+		MMCDEBUG("xmit\n");s->exchange(s,writebuff, readbuff, framelen);
+				
+		MMCDEBUG("interprete\n");
+		//locate and interprete the data
+		for(bytenum=COMMAND_LENGTH;bytenum<framelen;bytenum++)
+			if(!(readbuff[bytenum]&(u8)0x10))break;
+			//if(readbuff[bytenum]!=(u8)0xff)break;
+		
+		if(bytenum==(framelen)){
+			MMCDEBUG("no command response received\n");
+			s->tip(s,FALSE);
+			MMCERROR(1);
+			}
+			
+		MMCDEBUG("get_response\n");
+		Rx = get_response(response,readbuff,bytenum);
+		
+		if(blocking)busy_wait(s);
+		
+		s->tip(s,FALSE);//use caution inlining this as it turns off the transaction upon returning
+		return Rx;
+		
+	}
+
+/**
+	 * Block Read transaction
+	 * @param command - the initiating command
+	 * @param arg1 - arg1 of the initiating command
+	 * @param arg2 - arg2 of the initiating command
+	 * @param response - response size 
+	 * @param data - buffer to move received data into
+	 * @param blocknum - number of blocks to read
+	 * @param blocksize - size of blocks
+	 * @param Nac - Nac timing parameter
+	 * @return the total number of blocks read
+	 * 
+	 * major guts rewrite to accomodate new SPI bus method.
+	 * 
+	 */
+int mmcblockread(mmcslot_t *s, int command, int arg1, int arg2,int response, u8 *data,int blocksize, int blocknum,int Nac){
+		u8 frame[COMMAND_LENGTH+Ncr_MAX+MAX_RESPONSE];
+		int block;//current block being parsed
+		int frame_index;//frame index		
+		int Rx;
+		u8 CRC[CRC_LENGTH];
+		u8 commandbuffer[COMMAND_LENGTH];
+		
+		MMCDEBUG("BlockRead command %d\n",command);	
+		
+		//printk("BlockRead command %d\n",command);	
+		
+		packetize(commandbuffer,COMMAND_LENGTH,command,arg1,arg2);
+
+		if((s->tip(s,TRUE))<0)MMCERROR(1);//could not obtain the bus
+		s->exchange(s,commandbuffer, frame, sizeof(commandbuffer));
+		
+		//new broken up method cannot grab response within single xmit as it can 
+		//accidentally pull data. 
+		//Check the bytes as they are tranceived instead
+		MMCDEBUG("exchange response\n");
+		for(frame_index=COMMAND_LENGTH;frame_index<(COMMAND_LENGTH+Ncr_MAX+response);frame_index++){	
+			s->exchange(s,NULL,&frame[frame_index],1);
+			//if(frame[frame_index]!=(u8)0xff)break;//go ahead and interprete the response
+			if(!(frame[frame_index]&(u8)0x10))break;
+		}
+			
+		if(frame_index==(COMMAND_LENGTH+Ncr_MAX+response)){
+			printk("MMC READ:no command response received\n");
+			s->tip(s,FALSE);
+			MMCERROR(1);
+			}
+			
+		Rx = get_response(response,frame,frame_index);
+		
+		if(CommandResponse(Rx)<0){
+			printk("MMC_READ:command response error, Rx=%x\n",Rx);
+			s->tip(s,FALSE);
+			MMCERROR(1);//error
+		}
+		
+		MMCDEBUG("wait for rx token\n");
+		for(block=0;block<blocknum;block++){	
+			if(wait_for_Rxtoken(s)<0){
+				printk("MMC_READ:No Rx token received\n");
+				s->tip(s,FALSE);
+				MMCERROR(1);//error
+			}
+			
+			MMCDEBUG("exchange data block %u\n",block);	
+			//retrieve a block of data, passing null to tx assumes 0xff transmission
+			s->exchange(s,NULL,&data[block*blocksize],blocksize);
+			s->exchange(s,NULL,CRC,CRC_LENGTH);//not currently used
+											
+			}
+		
+		//Send extra 8 char NEC	
+		s->exchange(s,NULL, NULL,8);
+			
+		if(command==18)STOP_TRANSMISSION(s);//end open ended read		
+		s->tip(s,FALSE);		
+		return blocknum;
+		}
+
+	/**
+	 * Write Blocks of data;
+	 * @param command command index to initiate the transfer
+	 * @param arg1 first arguement to the command
+	 * @param arg2 second arguement to the commmand
+	 * @param response number of responses expected
+	 * @param data buffer holding the data to be transmitted
+	 * @param blocknum number of blocks
+	 * @param blocksize size of the blocks
+	 * @param Nwr timing parameter, typically 1
+	 * @return
+	 */
+int mmcblockwrite(mmcslot_t *s,int command, int arg1, int arg2, int response, u8 *data, int blocksize, int blocknum,int Nwr){		
+		int block;
+		int dataresponse;
+		u8 BW_STOP_TOKEN = 0xFD;	
+		u8 BW_START_TOKEN = 0xFD;
+		u8 commandbuffer[COMMAND_LENGTH+MAX_NWR+MAX_RESPONSE];
+		u8 responsebuffer[DATA_RESPONSE_LENGTH+CRC_LENGTH];
+		int index;
+
+		MMCDEBUG("BlockWrite:cmd %x arg1 %x arg2 %x size %x num%x\n",command,arg1,arg2,blocksize,blocknum);					
+				
+		//use the start correct token for single or multiple writes		
+		if(command==25)
+			BW_START_TOKEN = 0xFc;
+		else
+			BW_START_TOKEN = 0xFe;
+		
+		//transmit command and the first and possibly only block	
+		packetize(commandbuffer,sizeof(commandbuffer),command,arg1,arg2);
+			
+		if((s->tip(s,TRUE))<0)MMCERROR(1);//could not obtain the bus
+		//a simpler command exchange than read, is there a reason read doesn't use this?		
+		s->exchange(s,commandbuffer, NULL, COMMAND_LENGTH);
+		
+		for(index=COMMAND_LENGTH;
+		index<(COMMAND_LENGTH+MAX_NWR+MAX_RESPONSE);index++){
+			s->exchange(s,NULL, &commandbuffer[index], 1);
+			//if(commandbuffer[index]!=(u8)0xff)break;//go ahead and interprete the response
+			if(!(commandbuffer[index]&(u8)0x10))break;
+		}
+			
+		if(index==(COMMAND_LENGTH+MAX_NWR+MAX_RESPONSE)){
+			printk("MMC BWRITE:no command response received\n");
+			s->tip(s,FALSE);
+			MMCERROR(1);
+			}
+			
+		index = get_response(response,commandbuffer,index);
+		
+		if((CommandResponse(index))<0){
+			printk("MMC BWRITE command response error\n");
+			s->tip(s,FALSE);
+			MMCERROR(1);//error
+		}	
+		
+		s->exchange(s,NULL, NULL, 1);//NWR delay
+
+		for(block=0;block<blocknum;block++){
+			//send start token
+			s->exchange(s,&BW_START_TOKEN, NULL, START_TOKEN_LENGTH);
+			
+			//send data
+			s->exchange(s,&data[block*blocksize], NULL, blocksize);
+
+			//read dataresponse
+			s->exchange(s,NULL, responsebuffer, (DATA_RESPONSE_LENGTH+CRC_LENGTH));
+
+			dataresponse = responsebuffer[CRC_LENGTH];//gloss over the CRC for now	
+			if(DataResponse(dataresponse)<0){
+				 printk("MMC Data Response error\n");
+				s->tip(s,FALSE);
+				MMCERROR(1);//error
+			}
+			MMCDEBUG("Block %u\n",block);					
+			busy_wait(s);//wait for completion
+		}		
+
+		//send the end transmit command if it's a multiple block write(open ended)
+		if(command==25){
+			//send stop token
+			s->exchange(s,&BW_STOP_TOKEN, NULL, 1);				
+			busy_wait(s);
+		}		
+		
+		s->tip(s,FALSE);
+		return blocknum;
+	}
+
+
+static int clearandreset(mmcslot_t *s){
+	int retval;
+	s->setspeed(s,100000);//set spi speed to low for initial configuration as an spi device
+	//s->setspeed(s,10000);
+	s->card.blocklength = 512;/*default, change later if appropriate*/
+	s->card.sdhc=0;
+	
+	s->tip(s,FALSE);
+	mdelay(1);
+
+	if((s->tip(s,2))<0)MMCERROR(1);//could not obtain the bus, this may need to be a retry
+	s->exchange(s,NULL, NULL,100);//send string of NULLS (0xff for MMC/SD) to clear out the card	
+	s->tip(s,FALSE);
+
+	if((s->tip(s,TRUE))<0)MMCERROR(1);//could not obtain the bus, this may need to be a retry
+	s->exchange(s,NULL, NULL,100);//send string of NULLS (0xff for MMC/SD) to clear out the card	
+	s->tip(s,FALSE);
+	
+	MMCIDEBUG("GO_IDLE_STATE\n");
+	crcval=0x95;//hard coded crc for GO_IDLE_STATE
+	retval = GO_IDLE_STATE(s);//reset and start SPI mode
+	if(retval!=1){
+		printk("couldn't enter idle state, retval=%x\n",retval);
+		MMCERROR(1);
+	}
+	
+	MMCIDEBUG("retval=%x\n",retval);
+	
+	return 0;
+}
+
+/**
+	 * Initialize the MMC interface and the SPI interface controlling it.
+	 * Also read out the registers into shadow variables.
+	 */	
+int mmcinit(mmcslot_t *s){
+		u8 RegisterBuff[16];
+		int response,iteration,mult;
+		
+		clearandreset(s);
+	
+		MMCIDEBUG("SEND_IF_COND\n");
+		crcval=0x86;//hard coded crc for SEND_IF_COND
+		response = SEND_IF_COND(s);
+		MMCIDEBUG("response = 0x%x\n",response);
+		if(response==0x1aa){
+			printk("SD spec 2.0 detected\n");
+			s->card.sdhc=1;
+		}else clearandreset(s);//just in case the IF_COND command caused problems...
+		
+		for(iteration=0;iteration<1000;iteration++){
+			MMCIDEBUG("SEND_OP_COND\n");
+			mdelay(1);//wait a bit between each reset check, give it some time to think
+			if (s->card.sdhc==1)
+				response = SEND_OP_COND_SDHC(s);//read OCR, SDHC version
+			else 
+				response = SEND_OP_COND(s);//read OCR, a wait should be inserted here until the OCR indicates ready.
+			MMCDEBUG("response = %d\n",response);
+			if(response==0)
+				break;		
+		}	
+		
+		if(iteration==1000){
+			s->state=INVALID;
+			s->tip(s,FALSE);
+			MMCIDEBUG("MMC init timout");
+			MMCERROR(1);
+		}
+
+		//while(1);//debug lock
+		
+		MMCDEBUG("SEND_CID\n");
+				
+		if(SEND_CID(s,RegisterBuff)<0){
+			printk("MMC: no CID register found\n");
+			s->state=INVALID;
+			s->tip(s,FALSE);
+			MMCERROR(1);
+		}
+		else
+			parse_CID(&s->card.CID,RegisterBuff);	
+
+		MMCDEBUG("SEND_CSD\n");
+		
+		if(SEND_CSD(s,RegisterBuff)<0){
+			s->state=INVALID;
+			s->tip(s,FALSE);
+			MMCERROR(1);
+		}
+			
+		parse_CSD(&s->card.CSD,RegisterBuff);		
+		
+		if(s->card.CSD.SPEC_VERS==1){
+			printk("SDHC card detected\n");
+			s->card.sdhc=1;//probably already set anyway
+			parse_CSD_SDHC(&s->card.CSD,RegisterBuff);
+		}
+		else
+			s->card.sdhc=0;//spec version actually indicates density, not protocol
+		
+		s->card.sectors = s->card.CSD.C_SIZE+1;
+		if(s->card.sdhc){
+			s->card.blocklength=512;
+			s->card.sectors*=1000;
+			//s->card.size = s->card.blocklength*s->card.sectors*1000;
+			s->card.size = s->card.blocklength*s->card.sectors;
+		}
+		else {
+			s->card.blocklength = (1<<(s->card.CSD.READ_BL_LEN));		
+			mult = 1<<(s->card.CSD.C_SIZE_MULT+2);
+			MMCDEBUG("mult=%u\n",mult);		
+			s->card.sectors*=mult;
+			s->card.size = s->card.blocklength*s->card.sectors;
+		}
+				
+		MMCDEBUG("set sectors to %u\n",s->card.sectors);
+		
+		
+		switch(s->card.CSD.TRAN_SPEED&7){
+			case 1:
+			s->card.speed = 1000000;
+			break;
+			
+			case 2:			
+			s->card.speed = 10000000;//can't go faster than 10M
+			break;
+			
+			case 3:			
+			s->card.speed = 100000000;//can't go faster than 100M
+			break;
+			
+			default:
+			s->card.speed = 100000;
+			break;
+		}
+		s->setspeed(s,s->card.speed);//turn the socket speed up to the maximum the card can handle
+		
+	printk("MMC card detected: %s\n",s->card.CID.Product_name);
+	printk("revision: %u.%u\n",((s->card.CID.Product_revision&0xf0)>>4),(s->card.CID.Product_revision&0x0f));
+	printk("serial#: %lu\n",s->card.CID.Product_serial_number);	
+	printk("Block Length=%u\n",s->card.blocklength);	
+	printk("Size =%lu\n",s->card.size);	
+	printk("Speed=%lu\n",s->card.speed);
+		
+	s->state=VALID;
+	s->tip(s,FALSE);
+	return 0;											
+}
diff -Naur linux-2.6.25/drivers/misc/classes/pwm.c linux-2.6.25.ep93xx/drivers/misc/classes/pwm.c
--- linux-2.6.25/drivers/misc/classes/pwm.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/pwm.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,194 @@
+/**
+ * A class for simple pwm ports
+ * Several types of devices are available 
+ * which all export the same basic functionity 
+ * through differnet underlying methods
+ */
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include <linux/kdev_t.h>
+#include <linux/chelper.h>
+#include <linux/class/pwm.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_PWMCLASS_RTDM
+#include <rtdm/rtdm_driver.h>
+#include <linux/class/rtdm/pwm_rtdm.h>
+#define ATOMIC(a) RTDM_EXECUTE_ATOMICALLY(a)
+#else
+#define ATOMIC(a) a
+#endif //CONFIG_PWMCLASS_RTDM
+
+/************************************************************
+ * the global device class
+ */
+static struct class *pwmclass = NULL;
+
+struct class *pwm_declare(void){
+	if(!pwmclass){
+		printk("registering PWM class\n");
+		pwmclass=class_create(THIS_MODULE,"pwm");
+	}
+return pwmclass;
+}
+
+/***************************************************************************
+ * typical low level methods
+ */
+
+/** need to ajust this to use a clock method rather than getsysclock 
+static inline int us2reg(__u32 *value, int Mhz){
+		switch(get_sclk()){
+			case 66000000:{
+				const __u32 regmax = (0xffff/66);
+				if(*value>regmax)*value=regmax;
+				else *value*=66;
+				// pwms seem to do funny things when zeros are written to period or width;
+				if(*value==0)*value=1;
+				return 0;
+			}
+			default:return SYSCLOCK_UNSUPPORTED;
+	}
+}
+
+static inline int reg2us(__u32 *value){
+		switch(get_sclk()){
+			case 66000000:
+				*value/=66;
+				return 0;		
+			default:return SYSCLOCK_UNSUPPORTED;
+	}
+}
+*/ 
+ 
+int  pwm_widthus_write8(pwm_t *pwm, pwm_data data){iowrite8(data,pwm->widthus);return 0;}
+
+int  pwm_widthus_write16(pwm_t *pwm, pwm_data data){iowrite16(data,pwm->widthus);return 0;}
+
+int  pwm_periodus_write8(pwm_t *pwm, pwm_data data){iowrite8(data,pwm->periodus);return 0;}
+
+int  pwm_periodus_write16(pwm_t *pwm, pwm_data data){iowrite16(data,pwm->periodus);return 0;}
+
+int  pwm_empty_write(pwm_t *pwm, pwm_data data){return 0;}
+
+pwm_data pwm_widthus_read8(pwm_t *pwm){return ioread8(pwm->widthus);}
+
+pwm_data pwm_widthus_read16(pwm_t *pwm){return ioread16(pwm->widthus);}
+
+pwm_data pwm_periodus_read8(pwm_t *pwm){return ioread8(pwm->periodus);}
+
+pwm_data pwm_periodus_read16(pwm_t *pwm){return ioread16(pwm->periodus);}
+
+pwm_data pwm_widthusshadow_read(pwm_t *pwm){return pwm->widthus_shadow;}
+
+pwm_data pwm_ff_read(pwm_t *pwm){return 0xff;}
+	
+pwm_data pwm_zero_read(pwm_t *pwm){return 0;}
+
+/***************************************************************************
+ * Atomic method wrappers
+ */
+int atomic_pwm_widthus_write(pwm_t *pwm,pwm_data data){
+	ATOMIC(pwm->widthus_write(pwm,data);)
+	return 0;
+}
+	
+int atomic_pwm_periodus_write(pwm_t *pwm,pwm_data data){
+	ATOMIC(pwm->periodus_write(pwm,data);)
+	return 0;
+}
+
+int atomic_pwm_invert_write(pwm_t *pwm,pwm_data data){
+	ATOMIC(pwm->invert_write(pwm,data);)
+	return 0;
+}	
+	
+pwm_data atomic_pwm_widthus_read(pwm_t *pwm){
+	pwm_data retval;
+	ATOMIC(retval = pwm->widthus_read(pwm);)
+	return retval;
+}
+
+pwm_data atomic_pwm_periodus_read(pwm_t *pwm){
+	pwm_data retval;
+	ATOMIC(retval = pwm->periodus_read(pwm);)
+	return retval;
+}
+
+pwm_data atomic_pwm_invert_read(pwm_t *pwm){
+	pwm_data retval;
+	ATOMIC(retval = pwm->invert_read(pwm);)
+	return retval;
+}
+
+/************************************************************************************
+ * gpio sysfs operations
+ */
+#ifdef CONFIG_PWMCLASS_SYSFS
+
+static ssize_t pwm_widthus_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	pwm_t *pwm = cls->class_data;
+	pwm_data data = sfs_getint(buf,count,&size);
+	atomic_pwm_widthus_write(pwm, data);
+	return size;
+}
+
+static ssize_t pwm_periodus_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	pwm_t *pwm = cls->class_data;
+	pwm_data data = sfs_getint(buf,count,&size);
+	atomic_pwm_periodus_write(pwm, data);
+	return size;
+}
+
+static ssize_t pwm_invert_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	pwm_t *pwm = cls->class_data;
+	pwm_data data = sfs_getint(buf,count,&size);
+	atomic_pwm_invert_write(pwm, data);
+	return size;
+}
+
+static ssize_t pwm_widthus_show(struct class_device *cls, char *buf){
+	pwm_t *pwm = cls->class_data;
+	return sprintf(buf,"%u\r\n",atomic_pwm_widthus_read(pwm));
+}
+
+static ssize_t pwm_periodus_show(struct class_device *cls, char *buf){
+	pwm_t *pwm = cls->class_data;
+	return sprintf(buf,"%u\r\n",atomic_pwm_periodus_read(pwm));
+}
+
+static ssize_t pwm_invert_show(struct class_device *cls, char *buf){
+	pwm_t *pwm = cls->class_data;
+	return sprintf(buf,"%x\r\n",atomic_pwm_invert_read(pwm));
+}
+
+static CLASS_DEVICE_ATTR(widthus,S_IRUGO|S_IWUGO,pwm_widthus_show,pwm_widthus_store);
+static CLASS_DEVICE_ATTR(periodus,S_IRUGO|S_IWUGO,pwm_periodus_show,pwm_periodus_store);
+static CLASS_DEVICE_ATTR(inversion,S_IRUGO|S_IWUGO,pwm_invert_show,pwm_invert_store);
+
+#endif //CONFIG_PWMCLASS_SYSFS
+/***************************************************************************
+* class instantiation
+*/
+struct class_device *pwm_register_class_device(pwm_t *pwm){		
+	struct class *pwm_master = pwm_declare();
+	struct class_device *dev = class_device_create(pwm_master, NULL, MKDEV(0, 0), NULL, pwm->name);
+	dev->class_data = pwm;
+
+#ifdef CONFIG_PWMCLASS_SYSFS
+	if((pwm->widthus_write)&&(pwm->widthus_read))class_device_create_file(dev,&class_device_attr_widthus);
+	if((pwm->periodus_write)&&(pwm->periodus_read))class_device_create_file(dev,&class_device_attr_periodus);
+	if((pwm->invert_write)&&(pwm->invert_read))class_device_create_file(dev,&class_device_attr_inversion);
+#endif	 
+	 
+#ifdef CONFIG_PWMCLASS_RTDM
+	rt_pwm_device_create(pwm);
+#endif 
+
+	return dev;			
+}
diff -Naur linux-2.6.25/drivers/misc/classes/rtdm/gpio_rtdm.c linux-2.6.25.ep93xx/drivers/misc/classes/rtdm/gpio_rtdm.c
--- linux-2.6.25/drivers/misc/classes/rtdm/gpio_rtdm.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/rtdm/gpio_rtdm.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,99 @@
+/**
+ * A class for simple gpio ports
+ * Several types of general purpose devices are available 
+ * which all export the same basic functionity 
+ * through differenet underlying methods
+ * This class can also be used to export simple interfaces
+ * to an 8 bit port into user space
+ */
+
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/class/gpio.h>
+#include <linux/class/rtdm/gpio_rtdm.h>
+#include <rtdm/rtdm_driver.h>
+
+typedef struct rtgpio_device_s {
+struct rtdm_device rtd;
+gpio_t *gpio;//pointer to parent gpio structure.
+}rtgpio_device_t; 
+
+static int rt_gpio_open(struct rtdm_dev_context *context,
+                  rtdm_user_info_t *user_info, int oflags){
+    return 0;
+}
+
+static int rt_gpio_close(struct rtdm_dev_context *context,
+                   rtdm_user_info_t *user_info){
+return 0;
+}
+
+static int rt_gpio_ioctl(struct rtdm_dev_context *context,
+                   rtdm_user_info_t *user_info, int request, void *umem){
+    rtgpio_device_t *dev = container_of(context->device,rtgpio_device_t,rtd);
+    gpio_t *gpio = dev->gpio;
+       
+    gpio_data kmem[1];
+             
+	switch(request){
+	case DDRREAD:
+	if(gpio->ddr_read) kmem[0] = atomic_gpio_ddr_read(gpio);
+	else return -2;
+	return rtdm_safe_copy_to_user (user_info, umem, kmem, sizeof(gpio_data));		
+	
+	case DDRWRITE:
+	rtdm_safe_copy_from_user (user_info, kmem, umem, sizeof(gpio_data));	
+	if(gpio->ddr_write) atomic_gpio_ddr_write(gpio,kmem[0]);
+	else return -2;
+	return 0;
+	
+	case DATAREAD:
+	if(gpio->data_read)kmem[0] = atomic_gpio_data_read(gpio);
+	else return -2;
+	return rtdm_safe_copy_to_user (user_info, umem, kmem, sizeof(gpio_data));
+	
+	case DATAWRITE:
+	rtdm_safe_copy_from_user (user_info, kmem, umem, sizeof(gpio_data));	
+	if(gpio->data_write)atomic_gpio_data_write(gpio,kmem[0]);	
+	else return -2;
+	return 0;
+	}             
+                   	                 	
+return -1;//no such op, need to find the right op code for this.
+}
+
+
+static const struct rtdm_device __initdata device_tmpl = {
+    struct_version:     RTDM_DEVICE_STRUCT_VER,
+
+    device_flags:       RTDM_NAMED_DEVICE | RTDM_EXCLUSIVE,
+    device_name:        "",
+    open_rt:            rt_gpio_open,
+    ops: {
+        close_rt:      	rt_gpio_close,
+        ioctl_rt:       rt_gpio_ioctl,
+    },
+    device_class:       RTDM_CLASS_GPIO,
+    driver_name:        "gpio_rtd",
+    driver_version:     RTDM_DRIVER_VER(1, 0, 0),
+    peripheral_name:    "gpio",
+    provider_name:      "EMAC.Inc",
+};
+
+
+int rt_gpio_device_create(struct gpio_s *gpio){
+		rtgpio_device_t *dev = kmalloc(sizeof(rtgpio_device_t),GFP_KERNEL);
+		dev->gpio = gpio;
+		memcpy(&dev->rtd, &device_tmpl, sizeof(struct rtdm_device));
+		strncpy(dev->rtd.device_name, dev->gpio->name, RTDM_MAX_DEVNAME_LEN);
+		dev->rtd.device_sub_class = dev->gpio->subclass;
+		dev->rtd.proc_name = dev->gpio->name;
+		if(rtdm_dev_register(&dev->rtd)){
+			printk("couldn't register rtgpio device %s\n",dev->rtd.device_name);	
+			kfree(dev);
+			return -1;
+		}
+	return 	0;	
+}
+
+
diff -Naur linux-2.6.25/drivers/misc/classes/rtdm/Makefile linux-2.6.25.ep93xx/drivers/misc/classes/rtdm/Makefile
--- linux-2.6.25/drivers/misc/classes/rtdm/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/rtdm/Makefile	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,8 @@
+#
+# Makefile for the misc classes
+#
+
+EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai 
+obj-$(CONFIG_GPIOCLASS_RTDM)	+= gpio_rtdm.o
+obj-$(CONFIG_PWMCLASS_RTDM)		+= pwm_rtdm.o
+
diff -Naur linux-2.6.25/drivers/misc/classes/rtdm/pwm_rtdm.c linux-2.6.25.ep93xx/drivers/misc/classes/rtdm/pwm_rtdm.c
--- linux-2.6.25/drivers/misc/classes/rtdm/pwm_rtdm.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/rtdm/pwm_rtdm.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,95 @@
+/**
+ * A rtdm interface for pwm classes
+ */
+
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/class/pwm.h>
+#include <linux/class/pwm.h>
+#include <linux/class/rtdm/pwm_rtdm.h>
+#include <rtdm/rtdm_driver.h>
+
+typedef struct rtpwm_device_s {
+struct rtdm_device rtd;
+pwm_t *pwm;//pointer to parent pwm structure.
+}rtpwm_device_t; 
+
+static int rt_pwm_open(struct rtdm_dev_context *context,
+                  rtdm_user_info_t *user_info, int oflags){
+    return 0;
+}
+
+static int rt_pwm_close(struct rtdm_dev_context *context,
+                   rtdm_user_info_t *user_info){
+return 0;
+}
+
+static int rt_pwm_ioctl(struct rtdm_dev_context *context,
+                   rtdm_user_info_t *user_info, int request, void *umem){
+    rtpwm_device_t *dev = container_of(context->device,rtpwm_device_t,rtd);
+    pwm_t *pwm = dev->pwm;
+       
+    pwm_data kmem[1];
+             
+	switch(request){
+	case PERIODUSREAD:
+	if(pwm->periodus_read) kmem[0] = atomic_pwm_periodus_read(pwm);
+	else return -2;
+	return rtdm_safe_copy_to_user (user_info, umem, kmem, sizeof(pwm_data));		
+	
+	case PERIODUSWRITE:
+	rtdm_safe_copy_from_user (user_info, kmem, umem, sizeof(pwm_data));	
+	if(pwm->periodus_write) atomic_pwm_periodus_write(pwm,kmem[0]);
+	else return -2;
+	return 0;
+	
+	case WIDTHUSREAD:
+	if(pwm->widthus_read)kmem[0] = atomic_pwm_widthus_read(pwm);
+	else return -2;
+	return rtdm_safe_copy_to_user (user_info, umem, kmem, sizeof(pwm_data));
+	
+	case WIDTHUSWRITE:
+	rtdm_safe_copy_from_user (user_info, kmem, umem, sizeof(pwm_data));	
+	if(pwm->widthus_write)atomic_pwm_widthus_write(pwm,kmem[0]);	
+	else return -2;
+	return 0;
+	}             
+                   	                 	
+return -1;//no such op, need to find the right op code for this.
+}
+
+
+static const struct rtdm_device __initdata device_tmpl = {
+    struct_version:     RTDM_DEVICE_STRUCT_VER,
+
+    device_flags:       RTDM_NAMED_DEVICE | RTDM_EXCLUSIVE,
+    device_name:        "",
+    open_rt:            rt_pwm_open,
+    ops: {
+        close_rt:      	rt_pwm_close,
+        ioctl_rt:       rt_pwm_ioctl,
+    },
+    device_class:       RTDM_CLASS_PWM,
+    driver_name:        "pwm_rtd",
+    driver_version:     RTDM_DRIVER_VER(1, 0, 0),
+    peripheral_name:    "pwm",
+    provider_name:      "EMAC.Inc",
+};
+
+
+int rt_pwm_device_create(struct pwm_s *pwm){
+		rtpwm_device_t *dev = kmalloc(sizeof(rtpwm_device_t),GFP_KERNEL);
+		dev->pwm = pwm;
+		memcpy(&dev->rtd, &device_tmpl, sizeof(struct rtdm_device));
+		strncpy(dev->rtd.device_name, dev->pwm->name, RTDM_MAX_DEVNAME_LEN);
+		dev->rtd.device_sub_class = dev->pwm->subclass;
+		dev->rtd.proc_name = dev->pwm->name;
+		if(rtdm_dev_register(&dev->rtd)){
+			printk("couldn't register rtpwm device %s\n",dev->rtd.device_name);	
+			kfree(dev);
+			return -1;
+		}
+	return 	0;	
+}
+
+
diff -Naur linux-2.6.25/drivers/misc/classes/spi.c linux-2.6.25.ep93xx/drivers/misc/classes/spi.c
--- linux-2.6.25/drivers/misc/classes/spi.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/spi.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,211 @@
+/**
+ * A class for simple gpio ports
+ * Several types of general purpose devices are available 
+ * which all export the same basic functionity 
+ * through different underlying methods
+ * This class can also be used to export simple interfaces
+ * to an 8 bit port into user space
+ */
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include <linux/kdev_t.h>
+#include <linux/chelper.h>
+#include <linux/class/spi.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SPICLASS_RTDM
+#include <rtdm/rtdm_driver.h>
+#include <linux/class/rtdm/spi_rtdm.h>
+#define ATOMIC(a) RTDM_EXECUTE_ATOMICALLY(a)
+#else
+#define ATOMIC(a) a
+#endif //CONFIG_GPIOCLASS_RTDM
+
+#ifdef CONFIG_SPICLASS_CHAR
+#include <linux/class/char/spi_char.h>
+#endif
+
+/************************************************************
+ * the global device class
+ */
+static struct class *spiclass = NULL;
+
+struct class *spi_declare(void){
+	if(!spiclass){
+		printk("registering SPI class\n");
+		spiclass=class_create(THIS_MODULE,"spi");
+#ifdef CONFIG_SPICLASS_CHAR
+		spi_char_init();
+#endif
+	}
+	return spiclass;
+}
+
+/***************************************************************************
+ * Atomic method wrappers
+ */
+int atomic_spi_tip(struct spi_s *s,int ofs){
+	spi_data retval;
+	ATOMIC(retval = s->tip(s,ofs);)
+	return retval;
+}
+
+int atomic_spi_xmit(struct spi_s *s,u8 *mosi, u8 *miso, int size){
+	ATOMIC(s->xmit(s,mosi, miso, size);)
+	return 0;
+}
+
+int atomic_spi_tip_write(struct spi_s *s,spi_control config){
+	ATOMIC(s->tip(s,(config>0));)
+	return 0;
+}
+
+spi_control atomic_spi_tip_read(struct spi_s *s){
+	spi_data retval;
+	ATOMIC(retval = s->tip(s,TIPSTATUS);)
+	return (retval>0);
+}
+
+int atomic_spi_conf_write(struct spi_s *s,spi_control config){
+	ATOMIC(s->confwrite(s, config);)
+	return 0;
+}
+
+spi_control atomic_spi_conf_read(struct spi_s *s){
+	spi_control retval;
+	ATOMIC(retval = s->confread(s);)
+	return retval;
+}
+
+int atomic_spi_speed_write(struct spi_s *s,spi_control speed){
+	ATOMIC(s->speedwrite(s, speed);)
+	return 0;
+}
+
+spi_control atomic_spi_speed_read(struct spi_s *s){
+	spi_control retval;
+	ATOMIC(retval = s->speedread(s);)
+	return retval;
+}
+
+
+/***************************************************************************
+ * gpio sysfs operations
+ */
+#ifdef CONFIG_SPICLASS_SYSFS
+#define SPIXMITDELIM ","
+
+static ssize_t spi_xmit_store(struct class_device *cls, const char *buf,size_t count){
+	spi_t *s = cls->class_data;
+	size_t size;	
+	//atomic_spi_tip(s,TIPON);
+	if(s->buf){kfree(s->buf);s->bsize=0;} /* this is not safe unless buf is set to NULL on init */
+	//worst case allocation, char-delim-char-delim = count/2 * 4 bytes per word
+	s->buf = kmalloc(count*2, GFP_KERNEL);
+	s->bsize = sfs_getstream(buf,count,&size,SPIXMITDELIM,s->buf);
+	{
+	int i;
+	printk("%s-data: ",__FUNCTION__);
+	for(i=0;i<s->bsize;i++)printk("0x%x ",s->buf[i]);
+	printk("\n");
+	}
+	atomic_spi_xmit(s,s->buf, s->buf, s->bsize);
+	//atomic_spi_tip(s,TIPOFF);
+
+	return size;
+}
+
+static ssize_t spi_xmit_show(struct class_device *cls, char *buf){
+	spi_t *s = cls->class_data;
+	int chars=0;
+	int i;
+	
+	for(i=0;i<s->bsize;i++){
+		if(chars>=(PAGE_SIZE-10)){
+			chars+=sprintf(&buf[chars],"...OVF");
+			return chars;
+		}
+		if(i)chars+=sprintf(&buf[chars],SPIXMITDELIM);
+		chars+=sprintf(&buf[chars],"%x",s->buf[i]);
+	}
+	chars+=sprintf(&buf[chars],"\n");
+	return chars;
+}
+
+static ssize_t spi_flags_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	spi_t *s = cls->class_data;
+	spi_control data = sfs_getint(buf,count,&size);
+	atomic_spi_conf_write(s, data);
+	return size;
+}
+
+static ssize_t spi_flags_show(struct class_device *cls, char *buf){
+	spi_t *s = cls->class_data;
+	return sprintf(buf,"%x\r\n",atomic_spi_conf_read(s));
+}	
+
+static ssize_t spi_speed_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	spi_t *s = cls->class_data;
+	spi_control data = sfs_getint(buf,count,&size);
+	atomic_spi_speed_write(s, data);
+	return size;
+}
+
+static ssize_t spi_speed_show(struct class_device *cls, char *buf){
+	spi_t *s = cls->class_data;
+	return sprintf(buf,"%d\r\n",atomic_spi_speed_read(s));
+}	
+
+static ssize_t spi_tip_store(struct class_device *cls, const char *buf,size_t count){
+	size_t size;
+	spi_t *s = cls->class_data;
+	spi_data data = sfs_getint(buf,count,&size);
+	atomic_spi_tip_write(s,data);
+	return size;
+}
+
+static ssize_t spi_tip_show(struct class_device *cls, char *buf){
+	spi_t *s = cls->class_data;
+	return sprintf(buf,"%x\r\n",(atomic_spi_tip_read(s)));
+}
+
+static CLASS_DEVICE_ATTR(xmit,S_IRUGO|S_IWUGO,spi_xmit_show,spi_xmit_store);
+static CLASS_DEVICE_ATTR(tip,S_IRUGO|S_IWUGO,spi_tip_show,spi_tip_store);
+static CLASS_DEVICE_ATTR(speed,S_IRUGO|S_IWUGO,spi_speed_show,spi_speed_store);
+static CLASS_DEVICE_ATTR(conf,S_IRUGO|S_IWUGO,spi_flags_show,spi_flags_store);
+#endif //CONFIG_SPICLASS_SYSFS
+/***************************************************************************
+* class instantiation
+*/
+struct class_device *spi_register_class_device(spi_t *s){		
+struct class *spi_master = spi_declare();
+struct class_device *dev;	
+dev_t devnum = MKDEV(0, 0);
+
+#ifdef CONFIG_SPICLASS_CHAR
+devnum = spi_char_create(s);
+#endif	
+	
+dev = class_device_create(spi_master, NULL, devnum, NULL, s->name);
+dev->class_data = s;
+
+s->bsize = 0;
+s->buf = NULL;
+
+#ifdef CONFIG_SPICLASS_SYSFS
+	if(s->xmit)class_device_create_file(dev,&class_device_attr_xmit);
+	if(s->tip)class_device_create_file(dev,&class_device_attr_tip);
+	if((s->speedwrite)&&(s->speedread))class_device_create_file(dev,&class_device_attr_speed);
+	if((s->confwrite)&&(s->confread))class_device_create_file(dev,&class_device_attr_conf);
+	#endif	 
+
+#ifdef CONFIG_SPICLASS_RTDM
+	rt_spi_device_create(s);
+#endif
+
+return dev;			
+}
diff -Naur linux-2.6.25/drivers/misc/classes/spi_interface.c linux-2.6.25.ep93xx/drivers/misc/classes/spi_interface.c
--- linux-2.6.25/drivers/misc/classes/spi_interface.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/misc/classes/spi_interface.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,260 @@
+#include <linux/class/spi_interface.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/spi/spi.h>
+
+/**
+ * Provides an interface betwee the Linux SPI interface and the
+ * EMAC SPI class (lsi2esc).
+ * 
+ * Copyright (C) 2007, EMAC Inc
+ */
+
+//#define DEBUG_LSI
+
+#ifdef DEBUG_LSI
+#define DPRINTK(string, args...) printk("lsi2esc: " string, ##args)
+#else
+#define DPRINTK(string, args...)
+#endif
+
+
+/**
+ * function to set/clear a transfer-in-progrees for
+ * the given device. This function should be implemented
+ * by the driver itself to make sure that the same device
+ * is being accessed and as such this function does nothing
+ */
+int lsi2esc_spi_tip(struct spi_s *s, int ofs)
+{
+    DPRINTK("lsi2esc_spi_tip\n");
+    return 0;
+}
+
+/**
+ * function to transfer data on the SPI bus
+ * Data is written/read using an spi_sync call which causes
+ * the chip select to remain active throughout the entire transfer
+ * but also requires that the available size of the buffers is the
+ * sum of the write data plus the read data. i.e. to write an 8 bit
+ * command and read a 8 bit response the response would be stored in
+ * the last 8 bits of a 16 bit miso, the data to be written would need
+ * to be placed in the top 8 bits of a 16 bit mosi.
+ * Assumptions: MOSI and MISO can be the same buffer,
+ * if MOSI is NULL 0xFF is transmitted, if MISO is NULL
+ * received data is discarded, there is no limit on buffer
+ * size but both buffers must be the same size if they both exist.
+ * 
+ * @param s the EMAC SPI class device to tranfer data on
+ * @param mosi the transmit buffer (master->slave)
+ * @param miso the receive buffer (slave->master)
+ * @param size the size of the data to transfer
+ * @return 0 or negative error code
+ */ 
+int lsi2esc_spi_xmit(struct spi_s *s, u8 *mosi, u8 *miso, int size)
+{
+    int result = 0;
+    u8 *local_mosi = mosi;
+    u8 *local_miso = miso;
+    int temp_size;
+    struct spi_message msg;
+    struct spi_transfer msg_xfer =
+    {
+        .cs_change  = 0, /* hold cs for entire transfer */
+    };
+  
+    DPRINTK("lsi2esc_spi_xmit %d bytes\n", size);
+    
+    if (!local_mosi) {
+        if (!(local_mosi = kmalloc(size, GFP_KERNEL)))
+            return -ENOMEM;
+        memset(local_mosi, 0xFF, size);
+    }
+    if (!local_miso) {
+        /* data is discarded, but a buffer must exist */
+        if (!(local_miso = kmalloc(size, GFP_KERNEL)))
+            return -ENOMEM;
+    }
+#ifdef DEBUG_LSI
+    for(temp_size = size; temp_size > 0; temp_size--) {
+        DPRINTK("mosi[%d] = 0x%X\n", temp_size-1, mosi ? mosi[temp_size-1] : 0);
+    }
+#endif
+    spi_message_init(&msg);
+    msg_xfer.tx_buf = local_mosi;
+    msg_xfer.rx_buf = local_miso;
+    msg_xfer.len = size;
+    spi_message_add_tail(&msg_xfer, &msg);
+    
+    result = spi_sync(s->lsi, &msg);
+    
+#ifdef DEBUG_LSI
+    for(temp_size = size; temp_size > 0; temp_size--) {
+        DPRINTK("miso[%d] = 0x%X\n", temp_size-1, local_miso ? local_miso[temp_size-1] : 0);
+    }
+#endif
+
+    if (!mosi)
+        kfree(local_mosi);
+    if (!miso)
+        kfree(local_miso);
+
+    return result;    
+}
+
+/**
+ * function to read the current configuration settings
+ * @param s the EMAC SPI class device to read from
+ * @return the current configuration
+ */
+spi_control lsi2esc_spi_confread(struct spi_s *s)
+{
+    spi_control flags = 0;
+    DPRINTK("lsi2esc_spi_confread\n");
+
+    flags = s->lsi->mode; /* SPI and SPICL same here */
+
+    DPRINTK("bits_per_word = %d\n", s->lsi->bits_per_word);
+    if (s->lsi->bits_per_word == 8)
+        flags |= SPICL_EIGHTBIT; /* actually does nothing */
+    else if (s->lsi->bits_per_word == 10)
+        flags |= SPICL_TENBIT;
+    else if (s->lsi->bits_per_word == 12)
+        flags |= SPICL_TWELVEBIT;
+    else if (s->lsi->bits_per_word == 16)
+        flags |= SPICL_SIXTEENBIT;
+    
+    return flags;
+}
+
+/**
+ * function to change the current configuration settings
+ * @param s the EMAC SPI class device to configure
+ * @param config the new configuration to write
+ * @return 0 or the result of spi_setup
+ */
+int lsi2esc_spi_confwrite(struct spi_s *s, spi_control config)
+{
+    DPRINTK("lsi2esc_spi_confwrite: %d\n", config);
+    
+    /* set the mode */
+    s->lsi->mode = 0;
+    if (config & SPI_CPOL)
+        s->lsi->mode |= SPI_CPOL;
+    if (config & SPI_CPHA)
+        s->lsi->mode |= SPI_CPHA;
+    
+    /* explicitly set the bits per word if specified
+     * otherwise leave unchanged */
+    if (config & SPICL_EIGHTBIT)
+        s->lsi->bits_per_word = 8;
+    else if (config & SPICL_TENBIT)
+        s->lsi->bits_per_word = 10;
+    else if (config & SPICL_TWELVEBIT)
+        s->lsi->bits_per_word = 12;
+    else if (config & SPICL_SIXTEENBIT)
+        s->lsi->bits_per_word = 16;
+    
+    return spi_setup(s->lsi);
+}
+
+/**
+ * function to get the current speed settings
+ * @param s the EMAC SPI class device
+ * @return the speed setting of the associated spi_device
+ */
+spi_control lsi2esc_spi_speedread(struct spi_s *s)
+{
+    DPRINTK("lsi2esc_spi_speedread\n");
+    return s->lsi->max_speed_hz;    
+}
+
+/**
+ * function to change the speed settings
+ * @param s the EMAC SPI class device
+ * @param speed the new speed to set
+ */
+int lsi2esc_spi_speedwrite(struct spi_s *s, spi_control speed)
+{
+    DPRINTK("lsi2esc_spi_speedwrite\n");
+    s->lsi->max_speed_hz = speed;
+    /* error checking and adjustment must be provided by
+     * the SPI controller driver to use this directly */
+    return spi_setup(s->lsi);
+}
+
+/******************************************************************************/
+
+/**
+ * The lsi2esc interface actually acts like an SPI protocol driver.
+ * It fakes as an SPI device, but performs generic access to SPI
+ * only through the EMAC class interface rather than device specific
+ * access. The following section provides the SPI protocol driver
+ * code.
+ */
+
+/**
+ * probe function to initialize the interface
+ */
+
+static int __devinit lsi2esc_probe(struct spi_device *spi)
+{
+    struct spi_s *esc;
+    /* the platform data of dev must be set to the spi_t in
+     * the board specific file */
+    /* kind of creates a loop... but thats OK */
+    esc = spi->dev.platform_data;
+    esc->lsi = spi;
+
+
+    if (!esc)
+        return -ENODEV;
+    if (!spi_register_class_device(esc))
+        return -ENOMEM;
+
+    return 0;    
+}
+
+/**
+ * remove function to provide a clean exit
+ */
+
+static int __devexit lsi2esc_remove(struct spi_device *spi)
+{
+    /* nothing to do here */
+    return 0;
+}
+
+static struct spi_driver lsi2esc_driver = {
+    .driver = {
+        .name   = "lsi2esc",
+        .bus    = &spi_bus_type,
+        .owner  = THIS_MODULE,
+    },
+    .probe  = lsi2esc_probe,
+    .remove = __devexit_p(lsi2esc_remove),
+};
+
+static __init int lsi2esc_init(void)
+{
+    DPRINTK("Registering LSI2ESC SPI driver\n");
+    return spi_register_driver(&lsi2esc_driver);
+}
+
+static __exit void lsi2esc_exit(void)
+{
+    spi_unregister_driver(&lsi2esc_driver);
+}
+
+module_init(lsi2esc_init);
+module_exit(lsi2esc_exit);
+
+MODULE_AUTHOR("EMAC.Inc (support@emacinc.com)");
+MODULE_DESCRIPTION("Generic EMAC SPI class to Linux SPI Interface Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+// EOF
diff -Naur linux-2.6.25/include/linux/class/char/gpio_char.h linux-2.6.25.ep93xx/include/linux/class/char/gpio_char.h
--- linux-2.6.25/include/linux/class/char/gpio_char.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/include/linux/class/char/gpio_char.h	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,31 @@
+#ifndef GPIO_CHAR_H_
+#define GPIO_CHAR_H_
+
+#ifdef __KERNEL__
+int gpio_char_init(void);
+int gpio_char_create(struct gpio_s *gpio);
+
+#ifndef GPIO_MAJOR
+#define GPIO_MAJOR 0
+#endif
+
+/* we use the max_devs define to register a region on init */
+#define GPIO_MAX_DEVS 15
+#endif /*__KERNEL__*/
+
+/* This header defines the ioctl commands */
+#include <linux/class/rtdm/gpio_rtdm.h>
+
+#define CHAR_CLASS_GPIO RTDM_CLASS_GPIO
+/* the following are defined in gpio_rtdm.h */
+/*
+ * #define DDRREAD         _IOR(RTDM_CLASS_GPIO,0,char)
+ * #define DDRWRITE        _IOW(RTDM_CLASS_GPIO,0,char)
+ * #define DATAREAD        _IOR(RTDM_CLASS_GPIO,1,char)
+ * #define DATAWRITE       _IOW(RTDM_CLASS_GPIO,1,char)
+ // additions for the char driver
+ * #define INDEXREAD       _IOR(RTDM_CLASS_GPIO,2,char)
+ * #define INDEXWRITE      _IOW(RTDM_CLASS_GPIO,2,char)
+ */
+
+#endif /*GPIO_CHAR_H_*/
diff -Naur linux-2.6.25/include/linux/class/char/spi_char.h linux-2.6.25.ep93xx/include/linux/class/char/spi_char.h
--- linux-2.6.25/include/linux/class/char/spi_char.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/include/linux/class/char/spi_char.h	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,27 @@
+#ifndef SPI_CHAR_H_
+#define SPI_CHAR_H_
+
+#ifdef __KERNEL__
+int spi_char_init(void);
+int spi_char_create(struct spi_s *spi);
+
+#ifndef SPI_MAJOR
+#define SPI_MAJOR 0
+#endif
+
+/* we use the max_devs define to register a region on init */
+#define SPI_MAX_DEVS 15
+#endif /*__KERNEL__*/
+
+typedef struct spi_transfer_s{
+	spi_data *mosi;
+	spi_data *miso;
+	ssize_t size;
+}spi_transfer_t;
+
+/* This header defines the ioctl commands */
+#include <linux/class/rtdm/spi_rtdm.h>
+
+#define CHAR_CLASS_SPI RTDM_CLASS_SPI
+
+#endif /*SPI_CHAR_H_*/
diff -Naur linux-2.6.25/include/linux/class/rtdm/gpio_rtdm.h linux-2.6.25.ep93xx/include/linux/class/rtdm/gpio_rtdm.h
--- linux-2.6.25/include/linux/class/rtdm/gpio_rtdm.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/include/linux/class/rtdm/gpio_rtdm.h	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,21 @@
+#ifndef GPIO_RTDM_H_
+#define GPIO_RTDM_H_
+
+#include <linux/ioctl.h>
+
+//arbitrary assignment, come back to this later
+#define RTDM_CLASS_GPIO 0x80 
+
+#ifdef __KERNEL__	
+int rt_gpio_device_create(struct gpio_s *gpio);
+#endif//__KERNEL__
+
+#define DDRREAD			_IOR(RTDM_CLASS_GPIO,0,char)
+#define DDRWRITE 		_IOW(RTDM_CLASS_GPIO,0,char)
+#define DATAREAD		_IOR(RTDM_CLASS_GPIO,1,char)
+#define DATAWRITE 		_IOW(RTDM_CLASS_GPIO,1,char)
+/* additions for the char driver */
+#define INDEXREAD       _IOR(RTDM_CLASS_GPIO,2,char)
+#define INDEXWRITE      _IOW(RTDM_CLASS_GPIO,2,char)
+
+#endif //GPIO_RTDM_H_
diff -Naur linux-2.6.25/include/linux/class/rtdm/pwm_rtdm.h linux-2.6.25.ep93xx/include/linux/class/rtdm/pwm_rtdm.h
--- linux-2.6.25/include/linux/class/rtdm/pwm_rtdm.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/include/linux/class/rtdm/pwm_rtdm.h	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,18 @@
+#ifndef PWM_RTDM_H_
+#define PWM_RTDM_H_
+
+#include <linux/ioctl.h>
+
+//arbitrary assignment, come back to this later
+#define RTDM_CLASS_PWM 0x90 
+
+#ifdef __KERNEL__	
+int rt_pwm_device_create(struct pwm_s *pwm);
+#endif//__KERNEL__
+
+#define PERIODUSREAD		_IOR(RTDM_CLASS_PWM,0,char)
+#define PERIODUSWRITE 		_IOW(RTDM_CLASS_PWM,0,char)
+#define WIDTHUSREAD			_IOR(RTDM_CLASS_PWM,1,char)
+#define WIDTHUSWRITE 		_IOW(RTDM_CLASS_PWM,1,char)
+
+#endif //PWM_RTDM_H_
diff -Naur linux-2.6.25/include/linux/class/rtdm/spi_rtdm.h linux-2.6.25.ep93xx/include/linux/class/rtdm/spi_rtdm.h
--- linux-2.6.25/include/linux/class/rtdm/spi_rtdm.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/include/linux/class/rtdm/spi_rtdm.h	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,21 @@
+#ifndef SPI_RTDM_H_
+#define SPI_RTDM_H_
+
+#include <linux/ioctl.h>
+
+//arbitrary assignment, come back to this later
+#define RTDM_CLASS_SPI 0x90 
+
+#ifdef __KERNEL__	
+int rt_spi_device_create(struct spi_s *spi);
+#endif//__KERNEL__
+
+#define CONFREAD		_IOR(RTDM_CLASS_SPI,0,spi_control)
+#define CONFWRITE		_IOW(RTDM_CLASS_SPI,0,spi_control)
+#define SPEEDREAD		_IOR(RTDM_CLASS_SPI,1,spi_control)
+#define SPEEDWRITE		_IOW(RTDM_CLASS_SPI,1,spi_control)
+#define TIPREAD			_IOR(RTDM_CLASS_SPI,2,spi_control)
+#define TIPWRITE		_IOW(RTDM_CLASS_SPI,2,spi_control)
+#define XMIT			_IOW(RTDM_CLASS_SPI,3,spi_transfer_t)
+
+#endif //SPI_RTDM_H_
