diff -Naur linux-2.6.25/drivers/ioex/Kconfig linux-2.6.25.ep93xx/drivers/ioex/Kconfig
--- linux-2.6.25/drivers/ioex/Kconfig	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/ioex/Kconfig	2008-12-08 12:37:17.000000000 -0600
@@ -0,0 +1,52 @@
+#
+# IO expansion configuration
+#
+
+menu "IO expansion"
+
+config ECOREEX
+        tristate "EMAC cores"
+        ---help---
+        Provides autodetection and support for PLD cores following the EMAC 
+        format, which uses a device key to communicate the expansion devices available to 
+        the kernel.       
+
+config ECOREEX_TGPIO
+		depends on ECOREEX
+        bool "iPac True GPI/O expansion R1.0"
+        ---help---
+        Provides autodetection and support for the iPac GPI/O expansion
+
+config ECOREEX_SGPWM
+		depends on ECOREEX
+        bool "iPac Shadow GPI/O & PWM expansion R1.0"
+        ---help---
+        Provides autodetection and support for the iPac Shadow GPI/O & PWM expansion
+
+config ECOREEX_GCMB
+		depends on ECOREEX
+        bool "GCMB expansion I/O"
+        ---help---
+        Provides autodetection and support for the GCMB expansion
+
+config ECOREEX_SOM200
+		depends on ECOREEX
+        bool "EMAC SoM-200-ES expansion I/O"
+        ---help---
+        Provides support for the EMAC SoM-200-ES PLD
+        
+config BOARDSPEC
+        tristate "board devices"
+        ---help---
+        Provides registration of devices provided by the mach. 
+
+config PB1010
+        tristate "Shufflemaster PB1010 FPGA module"
+        ---help---
+        Provides support for the Shufflemaster FPGA module.
+
+endmenu
+
+
+
+
diff -Naur linux-2.6.25/drivers/ioex/Makefile linux-2.6.25.ep93xx/drivers/ioex/Makefile
--- linux-2.6.25/drivers/ioex/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/ioex/Makefile	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,11 @@
+#
+# Makefile for the ioex devices
+#
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ECOREEX)		+= ecoreex.o
+obj-$(CONFIG_BOARDSPEC)		+= boardspec.o
+obj-$(CONFIG_PB1010)		+= pb1010.o
+obj-y				+= pwmd.o
+
diff -Naur linux-2.6.25/drivers/ioex/pb1010.c linux-2.6.25.ep93xx/drivers/ioex/pb1010.c
--- linux-2.6.25/drivers/ioex/pb1010.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/ioex/pb1010.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,139 @@
+/***************************************************************************
+                          		pb1010.c    
+					pb1010 soft core mapping driver             
+                             -------------------
+	author				 : NZG
+    rewrite              : Fri Jun 08 2007
+    copyright          	 : (C) 2007 by EMAC.Inc
+    email                : support@emacinc.com
+ ***************************************************************************/
+ 
+#include <linux/kernel.h>
+#include <linux/autoconf.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/ioex/pb1010.h>
+#include <linux/platform_device.h>
+#include <linux/class/gpio.h>
+#include <linux/class/pwm.h>
+#include <asm/io.h>
+
+#define DRV_MODULE_NAME 	"pb1010"
+#define DRV_MODULE_VERSION 	"1.0"
+
+static int  gpio_data_write16(gpio_t *gpio, gpio_data data){iowrite16(data,gpio->data+gpio->index);gpio->shadow=data;return 0;}
+static gpio_data gpio_data_read16(gpio_t *gpio){return ioread16(gpio->data+gpio->index);}
+
+
+static inline struct class_device *gpio16_indexed_create(void *base,unsigned long size, const char *name){
+	gpio_t *gpio = kmalloc(sizeof(gpio_t),GFP_KERNEL);
+	memset(gpio,0,sizeof(gpio_t));
+	gpio->name = name;
+	gpio->subclass = GPIO_SUBCLASS;
+	gpio->data = base;
+	gpio->index = 0;
+	gpio->range=size;
+	gpio->data_write = gpio_data_write16;
+    gpio->data_read = gpio_data_read16;
+	gpio->index_write = gpio_index_write;
+    gpio->index_read = gpio_index_read;
+    printk("registering indexed gpio device: %s\n",name);
+    return gpio_register_class_device(gpio);
+}
+
+static inline struct class_device *gpio_indexed_create(void *base,unsigned long size, const char *name){
+	gpio_t *gpio = kmalloc(sizeof(gpio_t),GFP_KERNEL);
+	memset(gpio,0,sizeof(gpio_t));
+	gpio->name = name;
+	gpio->subclass = GPIO_SUBCLASS;
+	gpio->data = base;
+	gpio->index = 0;
+	gpio->range=size;
+	gpio->data_write = gpio_data_write8;
+    gpio->data_read = gpio_data_read8;
+	gpio->index_write = gpio_index_write;
+    gpio->index_read = gpio_index_read;
+    printk("registering indexed gpio device: %s\n",name);
+    return gpio_register_class_device(gpio);
+}
+
+/**
+ * create a generic index and data register pair for accessing the FPGA internals
+ */
+static inline int generic_map(unsigned long phys_addr,u8 *virt_addr,unsigned long size,const char *name,int flags){
+	
+	if(request_mem_region(phys_addr,size,name)==NULL){
+		printk("could not obtain physical memory at %lx for pb1010 core\n",phys_addr);
+		iounmap(virt_addr);
+		return -1;
+		}			
+	//add appropriate class devices for this version to the system
+	printk("%s detected at %lx\n",name,phys_addr);
+	
+#ifdef CONFIG_GPIOCLASS
+//gpio index from base to base+0x10000
+	if((flags&IORESOURCE_MEM_TYPE_MASK)==IORESOURCE_MEM_16BIT)gpio16_indexed_create((void *)virt_addr,size,name);
+	if((flags&IORESOURCE_MEM_TYPE_MASK)==IORESOURCE_MEM_8BIT)gpio_indexed_create((void *)virt_addr,size,name);
+#endif
+				
+return 0;
+}
+
+
+/************************************************************
+ * map fpga core into virtual memory and declare device classes
+ */
+static inline void map_core(unsigned long phys_addr, unsigned long size, int key_offset,const char *name,int flags)
+{	
+	u8 *virt_addr = ioremap_nocache(phys_addr,size);
+	int version;
+	
+	if(virt_addr==NULL)printk("could not remap physical memory at %lx for pb1010 core\n",phys_addr);
+	else{
+		//version =ioread8(&virt_addr[key_offset]);//key currently not implemented.
+		//printk("EMAC core version %x detected at %lx\n",version,phys_addr+key_offset );
+		generic_map(phys_addr,virt_addr,size,name,flags);
+		}
+}
+
+static int pb1010_probe(struct platform_device *pdev){
+	struct pb1010_data *data;
+	struct resource *r;
+	int i;
+
+	printk("pb1010_probe\n");	
+	if (pdev == NULL)return -ENODEV;
+	data = pdev->dev.platform_data;
+	
+	printk("num resources = %d\n",pdev->num_resources);
+		
+	for(i=0;i<pdev->num_resources;i++){
+	r = &pdev->resource[i];
+	map_core(r->start,(r->end-r->start+1),data->key_offset,r->name,r->flags);
+	//return 0;
+	}
+	return 0;
+}
+
+//driver currently has no removal method.
+static struct platform_driver pb1010_driver = {
+	.probe		= pb1010_probe,
+	.driver		= {
+		.name	= "pb1010",
+	},
+};
+
+static int __init pb1010_init_module(void)
+{
+	printk(KERN_INFO DRV_MODULE_NAME " version " DRV_MODULE_VERSION " loading\n");
+	return platform_driver_register(&pb1010_driver);
+}
+
+static void __exit pb1010_cleanup_module(void)
+{
+	platform_driver_unregister(&pb1010_driver);
+}
+
+
+module_init(pb1010_init_module);
+module_exit(pb1010_cleanup_module);
diff -Naur linux-2.6.25/drivers/ioex/pwmd.c linux-2.6.25.ep93xx/drivers/ioex/pwmd.c
--- linux-2.6.25/drivers/ioex/pwmd.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.25.ep93xx/drivers/ioex/pwmd.c	2008-08-18 14:05:42.000000000 -0500
@@ -0,0 +1,105 @@
+/**
+ * PWMD's 
+ * pwmd's modulate an external frequency, 
+ * this frequency is passed in as method, which is used to calcuate the widthus
+ * when written or read.
+*/
+
+#include <linux/class/pwm.h>
+#include <asm/io.h>
+
+#define PWMD_PWM_SUBCLASS 93
+
+#define REGMAX 255
+#define PERIODMAX ((0xffffffff)/(REGMAX))
+
+//internal errors
+#define SYSCLOCK_UNSUPPORTED	-2
+
+/**
+ * methods using a shadow register to set the periodus.
+ */
+static pwm_data pwmd_clock_read(struct pwm_s *pwm){
+	return pwm->periodus_shadow;
+}
+
+static int pwmd_clock_write(struct pwm_s *pwm,pwm_data clock){
+	if(!clock)clock=1;
+	if(clock>PERIODMAX)clock=PERIODMAX;//to prevent overflows
+	pwm->periodus_shadow = clock;
+	return 0;
+}
+
+static inline int us2reg(__u32 *value,__u32 periodus_in){
+	if(periodus_in)*value/=periodus_in;
+	//if the input period is zero written value has no effect and will be interpreted as zero in any case.
+	if(*value>REGMAX)*value=REGMAX;
+	return 0;
+}
+
+static inline int reg2us(__u32 *value,__u32 periodus_in){
+	*value*=periodus_in;
+	return 0;		
+}
+
+static int pwmd_widthus_write(struct pwm_s *pwm, pwm_data width){
+	pwm->widthus_shadow = width;
+	if(us2reg(&width,pwm->read_pwmclock(pwm))==SYSCLOCK_UNSUPPORTED)
+		{printk("sysclock unsupported\n");return SYSCLOCK_UNSUPPORTED;}
+	
+	iowrite16((u16)width,pwm->widthus);
+	return 0;
+}
+
+static pwm_data pwmd_widthus_read(struct pwm_s *pwm){
+	__u32 width = pwm->widthus_shadow;
+	
+	if(reg2us(&width,pwm->read_pwmclock(pwm))==SYSCLOCK_UNSUPPORTED)
+		{printk("sysclock unsupported\n");return SYSCLOCK_UNSUPPORTED;}
+		
+	return (width);
+}
+
+static pwm_data pwmd_periodus_read(struct pwm_s *pwm){
+	__u32 period = 0xff;
+	
+	if(reg2us(&period,pwm->read_pwmclock(pwm))==SYSCLOCK_UNSUPPORTED)
+		{printk("sysclock unsupported\n");return SYSCLOCK_UNSUPPORTED;}
+		
+	return (period); 
+}
+
+static int pwmd_periodus_write(struct pwm_s *pwm, pwm_data periodus){
+	pwmd_clock_write(pwm,periodus/REGMAX);
+	return 0;
+}
+
+struct class_device *pwmd_device_create(
+ void *widthus,
+ const char *name,
+ pwm_data (*read_pwmclock)(pwm_t *pwm)){
+	
+	pwm_t *pwm = kmalloc(sizeof(pwm_t),GFP_KERNEL);
+	memset(pwm,0,sizeof(pwm_t));
+	pwm->name = name;
+	pwm->subclass = PWMD_PWM_SUBCLASS;
+
+	pwm->widthus = widthus;
+	
+	pwm->widthus_write = pwmd_widthus_write;
+    pwm->widthus_read = pwmd_widthus_read;
+    pwm->periodus_read = pwmd_periodus_read;
+    
+	if(pwm->read_pwmclock)
+		pwm->periodus_write = pwm_empty_write;
+	else{
+		pwm->read_pwmclock = pwmd_clock_read;
+    	pwm->periodus_write = pwmd_periodus_write;
+    	pwmd_clock_write(pwm,1);
+	}
+	printk("registering pwmd device: %s\n",name);
+
+    return pwm_register_class_device(pwm);
+}
+
+
