Sorry, i did not test it properly before making the patches. Fixed ones
attached.

-- 
Lothar Gesslein <[EMAIL PROTECTED]>



(sorry mirabile, still with broken message id ;))
Index: target/linux/Config.in
===================================================================
--- target/linux/Config.in	(revision 861)
+++ target/linux/Config.in	(working copy)
@@ -729,6 +729,7 @@
 source package/alsa/Config.in
 source package/broadcom-wl/Config.in
 source package/broadcom-diag/Config.in
+source package/broadcom-mmc/Config.in
 source package/hostap/Config.in
 source package/madwifi/Config.in
 source package/mini_fo/Config.in
Index: package/Makefile
===================================================================
--- package/Makefile	(revision 861)
+++ package/Makefile	(working copy)
@@ -300,6 +300,7 @@
 package-$(FWRT_PACKAGE_ZLIB) += zlib
 # kernel addon packages
 package-$(FWRT_PACKAGE_KMOD_BROADCOM_DIAG) += broadcom-diag
+package-$(FWRT_PACKAGE_KMOD_BROADCOM_MMC) += broadcom-mmc
 package-$(FWRT_PACKAGE_KMOD_BROADCOM_WL) += broadcom-wl
 package-$(FWRT_PACKAGE_KMOD_MADWIFI) += madwifi
 package-$(FWRT_PACKAGE_KMOD_MINI_FO) += mini_fo
Index: package/broadcom-mmc/files/mmc.modules
===================================================================
--- package/broadcom-mmc/files/mmc.modules	(revision 0)
+++ package/broadcom-mmc/files/mmc.modules	(revision 0)
@@ -0,0 +1 @@
+mmc
Index: package/broadcom-mmc/src/mmc.c
===================================================================
--- package/broadcom-mmc/src/mmc.c	(revision 0)
+++ package/broadcom-mmc/src/mmc.c	(revision 0)
@@ -0,0 +1,676 @@
+#include <linux/delay.h>
+#include <linux/timer.h>
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/blkpg.h>
+#include <linux/hdreg.h>
+#include <linux/major.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define DEVICE_NAME "mmc"
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+#define MAJOR_NR 121
+
+#include <linux/blk.h>
+
+MODULE_AUTHOR("Madsuk/Rohde");
+MODULE_DESCRIPTION("Driver MMC/SD-Cards");
+MODULE_SUPPORTED_DEVICE("WRT54G");
+MODULE_LICENSE("GPL");
+
+#define SD_DI 0x20
+#define SD_DO 0x10
+#define SD_CLK 0x08
+#define SD_CS 0x80
+
+/* we have only one device */
+static int hd_sizes[1<<6];
+static int hd_blocksizes[1<<6];
+static int hd_hardsectsizes[1<<6];
+static int hd_maxsect[1<<6];
+static struct hd_struct hd[1<<6];
+
+static struct timer_list mmc_timer;
+static int mmc_media_detect = 0;
+static int mmc_media_changed = 1;
+
+typedef unsigned int uint32;
+
+static unsigned char port_state = 0x00;
+static volatile uint32 *gpioaddr_input = (uint32 *)0xb8000060;
+static volatile uint32 *gpioaddr_output = (uint32 *)0xb8000064;
+static volatile uint32 *gpioaddr_enable = (uint32 *)0xb8000068;
+static volatile uint32 *gpioaddr_control = (uint32 *)0xb800006c;
+
+static void mmc_spi_cs_low(void)
+{
+  port_state &= ~(SD_CS);
+  *gpioaddr_output = port_state;
+}
+
+static void mmc_spi_cs_high(void)
+{
+  port_state |= SD_CS;
+  *gpioaddr_output = port_state;
+}
+
+static unsigned char mmc_spi_io(unsigned char data_out)
+{
+  int i;
+  unsigned char result = 0, tmp_data = 0;
+  
+  for(i=0; i<8; i++) {
+    if(data_out & (0x01 << (7-i)))
+      port_state |= SD_DI;
+    else
+      port_state &= ~SD_DI;
+    
+    *gpioaddr_output = port_state;
+    port_state |= SD_CLK;
+    *gpioaddr_output = port_state;
+    
+    tmp_data = *gpioaddr_input;
+    
+    port_state &= ~SD_CLK;
+    *gpioaddr_output = port_state;
+    
+    result <<= 1;
+    
+    if(tmp_data & SD_DO)
+      result |= 1;
+  }
+  
+  return(result);
+}
+
+static int mmc_write_block(unsigned int dest_addr, unsigned char *data)
+{
+	unsigned int address;
+	unsigned char r = 0;
+	unsigned char ab0, ab1, ab2, ab3;
+	int i;
+
+	address = dest_addr;
+
+	ab3 = 0xff & (address >> 24);
+	ab2 = 0xff & (address >> 16);
+	ab1 = 0xff & (address >> 8);
+	ab0 = 0xff & address;
+	mmc_spi_cs_low();
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x58);
+	mmc_spi_io(ab3); /* msb */
+	mmc_spi_io(ab2);
+	mmc_spi_io(ab1);
+	mmc_spi_io(ab0); /* lsb */
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(1);
+	}
+
+	mmc_spi_io(0xfe);
+	for (i = 0; i < 512; i++) mmc_spi_io(data[i]);
+	for (i = 0; i < 2; i++) mmc_spi_io(0xff);
+
+	for (i = 0; i < 1000000; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0xff) break;
+	}
+	if (r != 0xff)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(3);
+	}
+	mmc_spi_cs_high();
+	mmc_spi_io(0xff);
+	return(0);
+}
+
+static int mmc_read_block(unsigned char *data, unsigned int src_addr)
+{
+	unsigned int address;
+	unsigned char r = 0;
+	unsigned char ab0, ab1, ab2, ab3;
+	int i;
+
+	address = src_addr;
+
+	ab3 = 0xff & (address >> 24);
+	ab2 = 0xff & (address >> 16);
+	ab1 = 0xff & (address >> 8);
+	ab0 = 0xff & address;
+
+	mmc_spi_cs_low();
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x51);
+	mmc_spi_io(ab3); /* msb */
+	mmc_spi_io(ab2);
+	mmc_spi_io(ab1);
+	mmc_spi_io(ab0); /* lsb */
+
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(1);
+	}
+	for (i = 0; i < 100000; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0xfe) break;
+	}
+	if (r != 0xfe)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(2);
+	}
+	for (i = 0; i < 512; i++)
+	{
+		r = mmc_spi_io(0xff);
+		data[i] = r;
+	}
+	for (i = 0; i < 2; i++)
+	{
+		r = mmc_spi_io(0xff);
+	}
+	mmc_spi_cs_high();
+	mmc_spi_io(0xff);
+
+	return(0);
+}
+
+static void mmc_request(request_queue_t *q)
+{
+	unsigned int mmc_address;
+	unsigned char *buffer_address;
+	int nr_sectors;
+	int i;
+	int cmd;
+	int rc, code;
+	
+	(void)q;
+	while (1)
+	{
+		code = 1; // Default is success
+		INIT_REQUEST;
+		mmc_address = (CURRENT->sector + hd[MINOR(CURRENT->rq_dev)].start_sect) * hd_hardsectsizes[0];
+		buffer_address = CURRENT->buffer;
+		nr_sectors = CURRENT->current_nr_sectors;
+		cmd = CURRENT->cmd;
+		if (((CURRENT->sector + CURRENT->current_nr_sectors + hd[MINOR(CURRENT->rq_dev)].start_sect) > hd[0].nr_sects) || (mmc_media_detect == 0))
+		{
+			code = 0;
+		}
+		else if (cmd == READ)
+		{
+			spin_unlock_irq(&io_request_lock);
+			for (i = 0; i < nr_sectors; i++)
+			{
+				rc = mmc_read_block(buffer_address, mmc_address);
+				if (rc != 0)
+				{
+					printk("mmc: error in mmc_read_block (%d)\n", rc);
+					code = 0;
+					break;
+				}
+				else
+				{
+					mmc_address += hd_hardsectsizes[0];
+					buffer_address += hd_hardsectsizes[0];
+				}
+			}
+			spin_lock_irq(&io_request_lock);
+		}
+		else if (cmd == WRITE)
+		{
+			spin_unlock_irq(&io_request_lock);
+			for (i = 0; i < nr_sectors; i++)
+			{
+				rc = mmc_write_block(mmc_address, buffer_address);
+				if (rc != 0)
+				{
+					printk("mmc: error in mmc_write_block (%d)\n", rc);
+					code = 0;
+					break;
+				}
+				else
+				{
+					mmc_address += hd_hardsectsizes[0];
+					buffer_address += hd_hardsectsizes[0];
+				}
+			}
+			spin_lock_irq(&io_request_lock);
+		}
+		else
+		{
+			code = 0;
+		}
+		end_request(code);
+	}
+}
+
+
+static int mmc_open(struct inode *inode, struct file *filp)
+{
+	int device;
+	(void)filp;
+	
+	if (mmc_media_detect == 0) return -ENODEV;
+
+#if defined(MODULE)
+	MOD_INC_USE_COUNT;
+#endif
+	return 0;
+}
+
+static int mmc_release(struct inode *inode, struct file *filp)
+{
+	(void)filp;
+	fsync_dev(inode->i_rdev);
+        invalidate_buffers(inode->i_rdev);
+
+#if defined(MODULE)
+	MOD_DEC_USE_COUNT;
+#endif
+	return 0;
+}
+
+extern struct gendisk hd_gendisk;
+static int mmc_revalidate(kdev_t dev)
+{
+	int target, max_p, start, i;
+	if (mmc_media_detect == 0) return -ENODEV;
+	
+	target = DEVICE_NR(dev);
+
+	max_p = hd_gendisk.max_p;
+	start = target << 6;
+	for (i = max_p - 1; i >= 0; i--) {
+		int minor = start + i;
+		invalidate_device(MKDEV(MAJOR_NR, minor), 1);
+		hd_gendisk.part[minor].start_sect = 0;
+		hd_gendisk.part[minor].nr_sects = 0;
+	}
+	
+	grok_partitions(&hd_gendisk, target, 1 << 6,
+			hd_sizes[0] * 2);
+
+	return 0;
+}
+
+static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	if (!inode || !inode->i_rdev)
+		return -EINVAL;
+
+	switch(cmd) {
+	case BLKGETSIZE:
+		return put_user(hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
+	case BLKGETSIZE64:
+		return put_user((u64)hd[MINOR(inode->i_rdev)].
+				nr_sects, (u64 *) arg);
+	case BLKRRPART:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+			
+		return mmc_revalidate(inode->i_rdev);
+	case HDIO_GETGEO:
+	{
+		struct hd_geometry *loc, g;
+		loc = (struct hd_geometry *) arg;
+		if (!loc)
+			return -EINVAL;
+		g.heads = 4;
+		g.sectors = 16;
+		g.cylinders = hd[0].nr_sects / (4 * 16);
+		g.start = hd[MINOR(inode->i_rdev)].start_sect;
+		return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
+	}
+	default:
+		return blk_ioctl(inode->i_rdev, cmd, arg);
+	}
+}
+
+static int mmc_card_init(void)
+{
+	unsigned char r = 0;
+	short i, j;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+        printk("mmc Card init\n");
+	mmc_spi_cs_high();
+	for (i = 0; i < 20; i++) mmc_spi_io(0xff);
+
+	mmc_spi_cs_low();
+
+	mmc_spi_io(0x40);
+	for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+	mmc_spi_io(0x95);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x01) break;
+	}
+	mmc_spi_cs_high();
+	mmc_spi_io(0xff);
+	if (r != 0x01)
+	{
+		restore_flags(flags);
+		return(1);
+	}
+
+        printk("mmc Card init *1*\n");
+	for (j = 0; j < 10000; j++)
+	{
+		mmc_spi_cs_low();
+
+		mmc_spi_io(0x41);
+		for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+		mmc_spi_io(0xff);
+		for (i = 0; i < 8; i++)
+		{
+			r = mmc_spi_io(0xff);
+			if (r == 0x00) break;
+		}
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		if (r == 0x00)
+		{
+			restore_flags(flags);
+			printk("mmc Card init *2*\n");
+			return(0);
+		}
+	}
+	restore_flags(flags);
+
+	return(2);
+}
+
+static int mmc_card_config(void)
+{
+	unsigned char r = 0;
+	short i;
+	unsigned char csd[32];
+	unsigned int c_size;
+	unsigned int c_size_mult;
+	unsigned int mult;
+	unsigned int read_bl_len;
+	unsigned int blocknr = 0;
+	unsigned int block_len = 0;
+	unsigned int size = 0;
+
+	mmc_spi_cs_low();
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x49);
+	for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(1);
+	}
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0xfe) break;
+	}
+	if (r != 0xfe)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(2);
+	}
+	for (i = 0; i < 16; i++)
+	{
+		r = mmc_spi_io(0xff);
+		csd[i] = r;
+	}
+	for (i = 0; i < 2; i++)
+	{
+		r = mmc_spi_io(0xff);
+	}
+	mmc_spi_cs_high();
+	mmc_spi_io(0xff);
+	if (r == 0x00) return(3);
+
+	c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
+	c_size >>= 6;
+	c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
+	c_size_mult >>= 7;
+	read_bl_len = csd[5] & 0x0f;
+	mult = 1;
+	mult <<= c_size_mult + 2;
+	blocknr = (c_size + 1) * mult;
+	block_len = 1;
+	block_len <<= read_bl_len;
+	size = block_len * blocknr;
+	size >>= 10;
+
+	for(i=0; i<(1<<6); i++) {
+	  hd_blocksizes[i] = 1024;
+	  hd_hardsectsizes[i] = block_len;
+	  hd_maxsect[i] = 256;
+	}
+	hd_sizes[0] = size;
+	hd[0].nr_sects = blocknr;
+
+
+	printk("Size = %d, hardsectsize = %d, sectors = %d\n",
+	       size, block_len, blocknr);
+
+	return 0;
+}
+
+static int mmc_hardware_init(void)
+{
+  unsigned char gpio_outen;
+  
+  // Set inputs/outputs here
+  printk("mmc Hardware init\n");
+  gpio_outen = *gpioaddr_enable;
+  
+  gpio_outen = (gpio_outen | SD_DI | SD_CLK | SD_CS) & ~SD_DO;
+  *gpioaddr_enable = gpio_outen;
+  
+  port_state = *gpioaddr_input;
+  
+  // Clock low
+  port_state &= ~(SD_CLK | SD_DI | SD_CS);
+  *gpioaddr_output = port_state;
+
+  return 0;
+}
+
+static int mmc_check_media_change(kdev_t dev)
+{
+	(void)dev;
+	if (mmc_media_changed == 1)
+	{
+		mmc_media_changed = 0;
+		return 1;
+	}
+	else return 0;
+}
+
+static struct block_device_operations mmc_bdops = 
+{
+	open: mmc_open,
+	release: mmc_release,
+	ioctl: mmc_ioctl,
+#if 0
+	check_media_change: mmc_check_media_change,
+	revalidate: mmc_revalidate,
+#endif
+};
+
+static struct gendisk hd_gendisk = {
+	major:		MAJOR_NR,
+	major_name:	DEVICE_NAME,
+	minor_shift:	6,
+	max_p:		1 << 6,
+	part:		hd,
+	sizes:		hd_sizes,
+	fops:		&mmc_bdops,
+};
+
+static int mmc_init(void)
+{
+	int rc;
+
+	rc = mmc_hardware_init(); 
+
+	if ( rc != 0)
+	{
+		printk("mmc: error in mmc_hardware_init (%d)\n", rc);
+		return -1;
+	}
+
+	rc = mmc_card_init(); 
+	if ( rc != 0)
+	{
+		// Give it an extra shot
+		rc = mmc_card_init(); 
+		if ( rc != 0)
+		{
+			printk("mmc: error in mmc_card_init (%d)\n", rc);
+			return -1;
+		}
+	}
+
+	memset(hd_sizes, 0, sizeof(hd_sizes));
+	rc = mmc_card_config(); 
+	if ( rc != 0)
+	{
+		printk("mmc: error in mmc_card_config (%d)\n", rc);
+		return -1;
+	}
+	
+
+	blk_size[MAJOR_NR] = hd_sizes;
+
+	memset(hd, 0, sizeof(hd));
+	hd[0].nr_sects = hd_sizes[0]*2;
+
+	blksize_size[MAJOR_NR] = hd_blocksizes;
+	hardsect_size[MAJOR_NR] = hd_hardsectsizes;
+	max_sectors[MAJOR_NR] = hd_maxsect;
+
+	hd_gendisk.nr_real = 1;
+
+	register_disk(&hd_gendisk, MKDEV(MAJOR_NR,0), 1<<6,
+		      &mmc_bdops, hd_sizes[0]*2);
+
+	return 0;
+}
+
+static void mmc_exit(void)
+{
+	blk_size[MAJOR_NR] = NULL;
+	blksize_size[MAJOR_NR] = NULL;
+	hardsect_size[MAJOR_NR] = NULL;
+	max_sectors[MAJOR_NR] = NULL;
+	hd[0].nr_sects = 0;
+}
+
+static void mmc_check_media(void)
+{
+	int old_state;
+	int rc;
+	
+	old_state = mmc_media_detect; 
+
+	// TODO: Add card detection here
+	mmc_media_detect = 1;
+	if (old_state != mmc_media_detect) 
+	{
+		mmc_media_changed = 1;
+		if (mmc_media_detect == 1)
+		{
+			rc = mmc_init();
+			if (rc != 0) printk("mmc: error in mmc_init (%d)\n", rc);
+		}
+		else 
+		{
+			mmc_exit();
+		}
+	}
+
+	/* del_timer(&mmc_timer);
+	mmc_timer.expires = jiffies + 10*HZ;
+	add_timer(&mmc_timer); */
+}
+
+static int __init mmc_driver_init(void)
+{
+	int rc;
+
+	rc = devfs_register_blkdev(MAJOR_NR, DEVICE_NAME, &mmc_bdops);
+	if (rc < 0)
+	{
+		printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR);
+		return rc;
+	}
+
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), mmc_request);
+
+	read_ahead[MAJOR_NR] = 8;
+	add_gendisk(&hd_gendisk);
+
+	mmc_check_media();
+
+	/*init_timer(&mmc_timer);
+	mmc_timer.expires = jiffies + HZ;
+	mmc_timer.function = (void *)mmc_check_media;
+	add_timer(&mmc_timer);*/
+
+	return 0;
+}
+
+static void __exit mmc_driver_exit(void)
+{
+	int i;
+	del_timer(&mmc_timer);
+
+	for (i = 0; i < (1 << 6); i++)
+		fsync_dev(MKDEV(MAJOR_NR, i));
+
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	del_gendisk(&hd_gendisk);
+	devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME);
+	mmc_exit();
+}
+
+module_init(mmc_driver_init);
+module_exit(mmc_driver_exit);
Index: package/broadcom-mmc/Config.in
===================================================================
--- package/broadcom-mmc/Config.in	(revision 0)
+++ package/broadcom-mmc/Config.in	(revision 0)
@@ -0,0 +1,6 @@
+config FWRT_PACKAGE_KMOD_BROADCOM_MMC
+	prompt "kmod-broadcom-mmc................. Kernel driver for the Linksys WRT54G MM/SD-Card Mod"
+	tristate
+	default n
+	help
+	  Kernel driver for the Linksys WRT54G MM/SD-Card Mod
Index: package/broadcom-mmc/ipkg/kmod-broadcom-mmc.control
===================================================================
--- package/broadcom-mmc/ipkg/kmod-broadcom-mmc.control	(revision 0)
+++ package/broadcom-mmc/ipkg/kmod-broadcom-mmc.control	(revision 0)
@@ -0,0 +1,4 @@
+Package: kmod-broadcom-mmc
+Priority: optional
+Section: sys
+Description: Kernel driver for the Linksys WRT54G MM/SD-Card Mod
Index: package/broadcom-mmc/Makefile
===================================================================
--- package/broadcom-mmc/Makefile	(revision 0)
+++ package/broadcom-mmc/Makefile	(revision 0)
@@ -0,0 +1,41 @@
+# $FreeWRT$
+#-
+# This file is part of the FreeWRT project. FreeWRT is copyrighted
+# material, please see the LICENCE file in the top-level directory
+# or at http://www.freewrt.org/licence for details.
+
+include $(TOPDIR)/rules.mk
+include $(TOPDIR)/mk/targets.mk
+
+PKG_NAME:=		broadcom-mmc
+PKG_VERSION:=		0.1
+PKG_RELEASE:=		1
+PKG_MODULE:=		20
+
+DISTFILES:=
+
+include $(TOPDIR)/mk/package.mk
+
+$(eval $(call PKG_template,KMOD_BROADCOM_MMC,kmod-$(PKG_NAME),$(KERNEL_VERSION)-$(BOARD)-$(PKG_RELEASE),$(ARCH),kernel ($(KERNEL_VERSION)-$(BOARD)-$(KERNEL_RELEASE))))
+
+COMPILE_FLAGS:= -O2 -DMODULE -D__KERNEL__  -W -Wall -Wstrict-prototypes -Wmissing-prototypes -fno-strict-aliasing -mips32 -I $(LINUX_DIR)/include -fno-pic -mno-abicalls -mlong-calls
+
+$(WRKBUILD)/.prepared:
+	mkdir -p $(WRKBUILD)
+	touch $@
+
+$(WRKBUILD)/.configured:
+	touch $@
+
+$(WRKBUILD)/.built:
+	$(TARGET_CC) $(COMPILE_FLAGS) -c -o $(WRKBUILD)/mmc.o src/mmc.c
+	touch $@
+	
+$(IPKG_KMOD_BROADCOM_MMC):
+	$(INSTALL_DIR) $(IDIR_KMOD_BROADCOM_MMC)/etc/modules.d
+	$(INSTALL_DIR) $(IDIR_KMOD_BROADCOM_MMC)/lib/modules/$(KERNEL_VERSION)
+	$(INSTALL_DATA) ./files/mmc.modules \
+		$(IDIR_KMOD_BROADCOM_MMC)/etc/modules.d/$(PKG_MODULE)-broadcom-mmc
+	$(INSTALL_DATA) $(WRKBUILD)/mmc.o \
+		$(IDIR_KMOD_BROADCOM_MMC)/lib/modules/$(KERNEL_VERSION)
+	$(IPKG_BUILD) $(IDIR_KMOD_BROADCOM_MMC) $(PACKAGE_DIR)
Index: target/linux/Config.in
===================================================================
--- target/linux/Config.in	(revision 861)
+++ target/linux/Config.in	(working copy)
@@ -728,6 +728,7 @@
 
 source package/alsa/Config.in
 source package/broadcom-wl/Config.in
+source package/broadcom-mmc/Config.in
 source package/broadcom-diag/Config.in
 source package/hostap/Config.in
 source package/madwifi/Config.in
Index: package/Makefile
===================================================================
--- package/Makefile	(revision 861)
+++ package/Makefile	(working copy)
@@ -301,6 +301,7 @@
 package-$(FWRT_PACKAGE_ZLIB) += zlib
 # kernel addon packages
 package-$(FWRT_PACKAGE_KMOD_BROADCOM_DIAG) += broadcom-diag
+package-$(FWRT_PACKAGE_KMOD_BROADCOM_MMC) += broadcom-mmc
 package-$(FWRT_PACKAGE_KMOD_BROADCOM_WL) += broadcom-wl
 package-$(FWRT_PACKAGE_KMOD_MADWIFI) += madwifi
 package-$(FWRT_PACKAGE_KMOD_MINI_FO) += mini_fo
Index: package/broadcom-mmc/files/mmc.modules
===================================================================
--- package/broadcom-mmc/files/mmc.modules	(revision 0)
+++ package/broadcom-mmc/files/mmc.modules	(revision 0)
@@ -0,0 +1 @@
+mmc
Index: package/broadcom-mmc/src/mmc.c
===================================================================
--- package/broadcom-mmc/src/mmc.c	(revision 0)
+++ package/broadcom-mmc/src/mmc.c	(revision 0)
@@ -0,0 +1,676 @@
+#include <linux/delay.h>
+#include <linux/timer.h>
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/blkpg.h>
+#include <linux/hdreg.h>
+#include <linux/major.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define DEVICE_NAME "mmc"
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+#define MAJOR_NR 121
+
+#include <linux/blk.h>
+
+MODULE_AUTHOR("Madsuk/Rohde");
+MODULE_DESCRIPTION("Driver MMC/SD-Cards");
+MODULE_SUPPORTED_DEVICE("WRT54G");
+MODULE_LICENSE("GPL");
+
+#define SD_DI 0x20
+#define SD_DO 0x10
+#define SD_CLK 0x08
+#define SD_CS 0x80
+
+/* we have only one device */
+static int hd_sizes[1<<6];
+static int hd_blocksizes[1<<6];
+static int hd_hardsectsizes[1<<6];
+static int hd_maxsect[1<<6];
+static struct hd_struct hd[1<<6];
+
+static struct timer_list mmc_timer;
+static int mmc_media_detect = 0;
+static int mmc_media_changed = 1;
+
+typedef unsigned int uint32;
+
+static unsigned char port_state = 0x00;
+static volatile uint32 *gpioaddr_input = (uint32 *)0xb8000060;
+static volatile uint32 *gpioaddr_output = (uint32 *)0xb8000064;
+static volatile uint32 *gpioaddr_enable = (uint32 *)0xb8000068;
+static volatile uint32 *gpioaddr_control = (uint32 *)0xb800006c;
+
+static void mmc_spi_cs_low(void)
+{
+  port_state &= ~(SD_CS);
+  *gpioaddr_output = port_state;
+}
+
+static void mmc_spi_cs_high(void)
+{
+  port_state |= SD_CS;
+  *gpioaddr_output = port_state;
+}
+
+static unsigned char mmc_spi_io(unsigned char data_out)
+{
+  int i;
+  unsigned char result = 0, tmp_data = 0;
+  
+  for(i=0; i<8; i++) {
+    if(data_out & (0x01 << (7-i)))
+      port_state |= SD_DI;
+    else
+      port_state &= ~SD_DI;
+    
+    *gpioaddr_output = port_state;
+    port_state |= SD_CLK;
+    *gpioaddr_output = port_state;
+    
+    tmp_data = *gpioaddr_input;
+    
+    port_state &= ~SD_CLK;
+    *gpioaddr_output = port_state;
+    
+    result <<= 1;
+    
+    if(tmp_data & SD_DO)
+      result |= 1;
+  }
+  
+  return(result);
+}
+
+static int mmc_write_block(unsigned int dest_addr, unsigned char *data)
+{
+	unsigned int address;
+	unsigned char r = 0;
+	unsigned char ab0, ab1, ab2, ab3;
+	int i;
+
+	address = dest_addr;
+
+	ab3 = 0xff & (address >> 24);
+	ab2 = 0xff & (address >> 16);
+	ab1 = 0xff & (address >> 8);
+	ab0 = 0xff & address;
+	mmc_spi_cs_low();
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x58);
+	mmc_spi_io(ab3); /* msb */
+	mmc_spi_io(ab2);
+	mmc_spi_io(ab1);
+	mmc_spi_io(ab0); /* lsb */
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(1);
+	}
+
+	mmc_spi_io(0xfe);
+	for (i = 0; i < 512; i++) mmc_spi_io(data[i]);
+	for (i = 0; i < 2; i++) mmc_spi_io(0xff);
+
+	for (i = 0; i < 1000000; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0xff) break;
+	}
+	if (r != 0xff)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(3);
+	}
+	mmc_spi_cs_high();
+	mmc_spi_io(0xff);
+	return(0);
+}
+
+static int mmc_read_block(unsigned char *data, unsigned int src_addr)
+{
+	unsigned int address;
+	unsigned char r = 0;
+	unsigned char ab0, ab1, ab2, ab3;
+	int i;
+
+	address = src_addr;
+
+	ab3 = 0xff & (address >> 24);
+	ab2 = 0xff & (address >> 16);
+	ab1 = 0xff & (address >> 8);
+	ab0 = 0xff & address;
+
+	mmc_spi_cs_low();
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x51);
+	mmc_spi_io(ab3); /* msb */
+	mmc_spi_io(ab2);
+	mmc_spi_io(ab1);
+	mmc_spi_io(ab0); /* lsb */
+
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(1);
+	}
+	for (i = 0; i < 100000; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0xfe) break;
+	}
+	if (r != 0xfe)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(2);
+	}
+	for (i = 0; i < 512; i++)
+	{
+		r = mmc_spi_io(0xff);
+		data[i] = r;
+	}
+	for (i = 0; i < 2; i++)
+	{
+		r = mmc_spi_io(0xff);
+	}
+	mmc_spi_cs_high();
+	mmc_spi_io(0xff);
+
+	return(0);
+}
+
+static void mmc_request(request_queue_t *q)
+{
+	unsigned int mmc_address;
+	unsigned char *buffer_address;
+	int nr_sectors;
+	int i;
+	int cmd;
+	int rc, code;
+	
+	(void)q;
+	while (1)
+	{
+		code = 1; // Default is success
+		INIT_REQUEST;
+		mmc_address = (CURRENT->sector + hd[MINOR(CURRENT->rq_dev)].start_sect) * hd_hardsectsizes[0];
+		buffer_address = CURRENT->buffer;
+		nr_sectors = CURRENT->current_nr_sectors;
+		cmd = CURRENT->cmd;
+		if (((CURRENT->sector + CURRENT->current_nr_sectors + hd[MINOR(CURRENT->rq_dev)].start_sect) > hd[0].nr_sects) || (mmc_media_detect == 0))
+		{
+			code = 0;
+		}
+		else if (cmd == READ)
+		{
+			spin_unlock_irq(&io_request_lock);
+			for (i = 0; i < nr_sectors; i++)
+			{
+				rc = mmc_read_block(buffer_address, mmc_address);
+				if (rc != 0)
+				{
+					printk("mmc: error in mmc_read_block (%d)\n", rc);
+					code = 0;
+					break;
+				}
+				else
+				{
+					mmc_address += hd_hardsectsizes[0];
+					buffer_address += hd_hardsectsizes[0];
+				}
+			}
+			spin_lock_irq(&io_request_lock);
+		}
+		else if (cmd == WRITE)
+		{
+			spin_unlock_irq(&io_request_lock);
+			for (i = 0; i < nr_sectors; i++)
+			{
+				rc = mmc_write_block(mmc_address, buffer_address);
+				if (rc != 0)
+				{
+					printk("mmc: error in mmc_write_block (%d)\n", rc);
+					code = 0;
+					break;
+				}
+				else
+				{
+					mmc_address += hd_hardsectsizes[0];
+					buffer_address += hd_hardsectsizes[0];
+				}
+			}
+			spin_lock_irq(&io_request_lock);
+		}
+		else
+		{
+			code = 0;
+		}
+		end_request(code);
+	}
+}
+
+
+static int mmc_open(struct inode *inode, struct file *filp)
+{
+	int device;
+	(void)filp;
+	
+	if (mmc_media_detect == 0) return -ENODEV;
+
+#if defined(MODULE)
+	MOD_INC_USE_COUNT;
+#endif
+	return 0;
+}
+
+static int mmc_release(struct inode *inode, struct file *filp)
+{
+	(void)filp;
+	fsync_dev(inode->i_rdev);
+        invalidate_buffers(inode->i_rdev);
+
+#if defined(MODULE)
+	MOD_DEC_USE_COUNT;
+#endif
+	return 0;
+}
+
+extern struct gendisk hd_gendisk;
+static int mmc_revalidate(kdev_t dev)
+{
+	int target, max_p, start, i;
+	if (mmc_media_detect == 0) return -ENODEV;
+	
+	target = DEVICE_NR(dev);
+
+	max_p = hd_gendisk.max_p;
+	start = target << 6;
+	for (i = max_p - 1; i >= 0; i--) {
+		int minor = start + i;
+		invalidate_device(MKDEV(MAJOR_NR, minor), 1);
+		hd_gendisk.part[minor].start_sect = 0;
+		hd_gendisk.part[minor].nr_sects = 0;
+	}
+	
+	grok_partitions(&hd_gendisk, target, 1 << 6,
+			hd_sizes[0] * 2);
+
+	return 0;
+}
+
+static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	if (!inode || !inode->i_rdev)
+		return -EINVAL;
+
+	switch(cmd) {
+	case BLKGETSIZE:
+		return put_user(hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
+	case BLKGETSIZE64:
+		return put_user((u64)hd[MINOR(inode->i_rdev)].
+				nr_sects, (u64 *) arg);
+	case BLKRRPART:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+			
+		return mmc_revalidate(inode->i_rdev);
+	case HDIO_GETGEO:
+	{
+		struct hd_geometry *loc, g;
+		loc = (struct hd_geometry *) arg;
+		if (!loc)
+			return -EINVAL;
+		g.heads = 4;
+		g.sectors = 16;
+		g.cylinders = hd[0].nr_sects / (4 * 16);
+		g.start = hd[MINOR(inode->i_rdev)].start_sect;
+		return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
+	}
+	default:
+		return blk_ioctl(inode->i_rdev, cmd, arg);
+	}
+}
+
+static int mmc_card_init(void)
+{
+	unsigned char r = 0;
+	short i, j;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+        printk("mmc Card init\n");
+	mmc_spi_cs_high();
+	for (i = 0; i < 20; i++) mmc_spi_io(0xff);
+
+	mmc_spi_cs_low();
+
+	mmc_spi_io(0x40);
+	for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+	mmc_spi_io(0x95);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x01) break;
+	}
+	mmc_spi_cs_high();
+	mmc_spi_io(0xff);
+	if (r != 0x01)
+	{
+		restore_flags(flags);
+		return(1);
+	}
+
+        printk("mmc Card init *1*\n");
+	for (j = 0; j < 10000; j++)
+	{
+		mmc_spi_cs_low();
+
+		mmc_spi_io(0x41);
+		for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+		mmc_spi_io(0xff);
+		for (i = 0; i < 8; i++)
+		{
+			r = mmc_spi_io(0xff);
+			if (r == 0x00) break;
+		}
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		if (r == 0x00)
+		{
+			restore_flags(flags);
+			printk("mmc Card init *2*\n");
+			return(0);
+		}
+	}
+	restore_flags(flags);
+
+	return(2);
+}
+
+static int mmc_card_config(void)
+{
+	unsigned char r = 0;
+	short i;
+	unsigned char csd[32];
+	unsigned int c_size;
+	unsigned int c_size_mult;
+	unsigned int mult;
+	unsigned int read_bl_len;
+	unsigned int blocknr = 0;
+	unsigned int block_len = 0;
+	unsigned int size = 0;
+
+	mmc_spi_cs_low();
+	for (i = 0; i < 4; i++) mmc_spi_io(0xff);
+	mmc_spi_io(0x49);
+	for (i = 0; i < 4; i++) mmc_spi_io(0x00);
+	mmc_spi_io(0xff);
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0x00) break;
+	}
+	if (r != 0x00)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(1);
+	}
+	for (i = 0; i < 8; i++)
+	{
+		r = mmc_spi_io(0xff);
+		if (r == 0xfe) break;
+	}
+	if (r != 0xfe)
+	{
+		mmc_spi_cs_high();
+		mmc_spi_io(0xff);
+		return(2);
+	}
+	for (i = 0; i < 16; i++)
+	{
+		r = mmc_spi_io(0xff);
+		csd[i] = r;
+	}
+	for (i = 0; i < 2; i++)
+	{
+		r = mmc_spi_io(0xff);
+	}
+	mmc_spi_cs_high();
+	mmc_spi_io(0xff);
+	if (r == 0x00) return(3);
+
+	c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
+	c_size >>= 6;
+	c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
+	c_size_mult >>= 7;
+	read_bl_len = csd[5] & 0x0f;
+	mult = 1;
+	mult <<= c_size_mult + 2;
+	blocknr = (c_size + 1) * mult;
+	block_len = 1;
+	block_len <<= read_bl_len;
+	size = block_len * blocknr;
+	size >>= 10;
+
+	for(i=0; i<(1<<6); i++) {
+	  hd_blocksizes[i] = 1024;
+	  hd_hardsectsizes[i] = block_len;
+	  hd_maxsect[i] = 256;
+	}
+	hd_sizes[0] = size;
+	hd[0].nr_sects = blocknr;
+
+
+	printk("Size = %d, hardsectsize = %d, sectors = %d\n",
+	       size, block_len, blocknr);
+
+	return 0;
+}
+
+static int mmc_hardware_init(void)
+{
+  unsigned char gpio_outen;
+  
+  // Set inputs/outputs here
+  printk("mmc Hardware init\n");
+  gpio_outen = *gpioaddr_enable;
+  
+  gpio_outen = (gpio_outen | SD_DI | SD_CLK | SD_CS) & ~SD_DO;
+  *gpioaddr_enable = gpio_outen;
+  
+  port_state = *gpioaddr_input;
+  
+  // Clock low
+  port_state &= ~(SD_CLK | SD_DI | SD_CS);
+  *gpioaddr_output = port_state;
+
+  return 0;
+}
+
+static int mmc_check_media_change(kdev_t dev)
+{
+	(void)dev;
+	if (mmc_media_changed == 1)
+	{
+		mmc_media_changed = 0;
+		return 1;
+	}
+	else return 0;
+}
+
+static struct block_device_operations mmc_bdops = 
+{
+	open: mmc_open,
+	release: mmc_release,
+	ioctl: mmc_ioctl,
+#if 0
+	check_media_change: mmc_check_media_change,
+	revalidate: mmc_revalidate,
+#endif
+};
+
+static struct gendisk hd_gendisk = {
+	major:		MAJOR_NR,
+	major_name:	DEVICE_NAME,
+	minor_shift:	6,
+	max_p:		1 << 6,
+	part:		hd,
+	sizes:		hd_sizes,
+	fops:		&mmc_bdops,
+};
+
+static int mmc_init(void)
+{
+	int rc;
+
+	rc = mmc_hardware_init(); 
+
+	if ( rc != 0)
+	{
+		printk("mmc: error in mmc_hardware_init (%d)\n", rc);
+		return -1;
+	}
+
+	rc = mmc_card_init(); 
+	if ( rc != 0)
+	{
+		// Give it an extra shot
+		rc = mmc_card_init(); 
+		if ( rc != 0)
+		{
+			printk("mmc: error in mmc_card_init (%d)\n", rc);
+			return -1;
+		}
+	}
+
+	memset(hd_sizes, 0, sizeof(hd_sizes));
+	rc = mmc_card_config(); 
+	if ( rc != 0)
+	{
+		printk("mmc: error in mmc_card_config (%d)\n", rc);
+		return -1;
+	}
+	
+
+	blk_size[MAJOR_NR] = hd_sizes;
+
+	memset(hd, 0, sizeof(hd));
+	hd[0].nr_sects = hd_sizes[0]*2;
+
+	blksize_size[MAJOR_NR] = hd_blocksizes;
+	hardsect_size[MAJOR_NR] = hd_hardsectsizes;
+	max_sectors[MAJOR_NR] = hd_maxsect;
+
+	hd_gendisk.nr_real = 1;
+
+	register_disk(&hd_gendisk, MKDEV(MAJOR_NR,0), 1<<6,
+		      &mmc_bdops, hd_sizes[0]*2);
+
+	return 0;
+}
+
+static void mmc_exit(void)
+{
+	blk_size[MAJOR_NR] = NULL;
+	blksize_size[MAJOR_NR] = NULL;
+	hardsect_size[MAJOR_NR] = NULL;
+	max_sectors[MAJOR_NR] = NULL;
+	hd[0].nr_sects = 0;
+}
+
+static void mmc_check_media(void)
+{
+	int old_state;
+	int rc;
+	
+	old_state = mmc_media_detect; 
+
+	// TODO: Add card detection here
+	mmc_media_detect = 1;
+	if (old_state != mmc_media_detect) 
+	{
+		mmc_media_changed = 1;
+		if (mmc_media_detect == 1)
+		{
+			rc = mmc_init();
+			if (rc != 0) printk("mmc: error in mmc_init (%d)\n", rc);
+		}
+		else 
+		{
+			mmc_exit();
+		}
+	}
+
+	/* del_timer(&mmc_timer);
+	mmc_timer.expires = jiffies + 10*HZ;
+	add_timer(&mmc_timer); */
+}
+
+static int __init mmc_driver_init(void)
+{
+	int rc;
+
+	rc = devfs_register_blkdev(MAJOR_NR, DEVICE_NAME, &mmc_bdops);
+	if (rc < 0)
+	{
+		printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR);
+		return rc;
+	}
+
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), mmc_request);
+
+	read_ahead[MAJOR_NR] = 8;
+	add_gendisk(&hd_gendisk);
+
+	mmc_check_media();
+
+	/*init_timer(&mmc_timer);
+	mmc_timer.expires = jiffies + HZ;
+	mmc_timer.function = (void *)mmc_check_media;
+	add_timer(&mmc_timer);*/
+
+	return 0;
+}
+
+static void __exit mmc_driver_exit(void)
+{
+	int i;
+	del_timer(&mmc_timer);
+
+	for (i = 0; i < (1 << 6); i++)
+		fsync_dev(MKDEV(MAJOR_NR, i));
+
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	del_gendisk(&hd_gendisk);
+	devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME);
+	mmc_exit();
+}
+
+module_init(mmc_driver_init);
+module_exit(mmc_driver_exit);
Index: package/broadcom-mmc/Config.in
===================================================================
--- package/broadcom-mmc/Config.in	(revision 0)
+++ package/broadcom-mmc/Config.in	(revision 0)
@@ -0,0 +1,6 @@
+config FWRT_PACKAGE_KMOD_BROADCOM_MMC
+	prompt "kmod-broadcom-mmc................. Kernel driver for the Linksys WRT54G MM/SD-Card Mod"
+	tristate
+	default n
+	help
+	  Kernel driver for the Linksys WRT54G MM/SD-Card Mod
Index: package/broadcom-mmc/ipkg/kmod-broadcom-mmc.control
===================================================================
--- package/broadcom-mmc/ipkg/kmod-broadcom-mmc.control	(revision 0)
+++ package/broadcom-mmc/ipkg/kmod-broadcom-mmc.control	(revision 0)
@@ -0,0 +1,4 @@
+Package: kmod-broadcom-mmc
+Priority: optional
+Section: sys
+Description: Kernel driver for the Linksys WRT54G MM/SD-Card Mod
Index: package/broadcom-mmc/Makefile
===================================================================
--- package/broadcom-mmc/Makefile	(revision 0)
+++ package/broadcom-mmc/Makefile	(revision 0)
@@ -0,0 +1,41 @@
+# $FreeWRT$
+#-
+# This file is part of the FreeWRT project. FreeWRT is copyrighted
+# material, please see the LICENCE file in the top-level directory
+# or at http://www.freewrt.org/licence for details.
+
+include $(TOPDIR)/rules.mk
+include $(TOPDIR)/mk/targets.mk
+
+PKG_NAME:=		broadcom-mmc
+PKG_VERSION:=		0.1
+PKG_RELEASE:=		1
+PKG_MODULE:=		20
+
+DISTFILES:=
+
+include $(TOPDIR)/mk/package.mk
+
+$(eval $(call PKG_template,KMOD_BROADCOM_MMC,kmod-$(PKG_NAME),$(KERNEL_VERSION)-$(BOARD)-$(PKG_RELEASE),$(ARCH),kernel ($(KERNEL_VERSION)-$(BOARD)-$(KERNEL_RELEASE))))
+
+COMPILE_FLAGS:= -O2 -DMODULE -D__KERNEL__  -W -Wall -Wstrict-prototypes -Wmissing-prototypes -fno-strict-aliasing -mips32 -I $(LINUX_DIR)/include -fno-pic -mno-abicalls -mlong-calls
+
+$(WRKBUILD)/.prepared:
+	mkdir -p $(WRKBUILD)
+	touch $@
+
+$(WRKBUILD)/.configured:
+	touch $@
+
+$(WRKBUILD)/.built:
+	$(TARGET_CC) $(COMPILE_FLAGS) -c -o $(WRKBUILD)/mmc.o src/mmc.c
+	touch $@
+	
+$(IPKG_KMOD_BROADCOM_MMC):
+	$(INSTALL_DIR) $(IDIR_KMOD_BROADCOM_MMC)/etc/modules.d
+	$(INSTALL_DIR) $(IDIR_KMOD_BROADCOM_MMC)/lib/modules/$(KERNEL_VERSION)
+	$(INSTALL_DATA) ./files/mmc.modules \
+		$(IDIR_KMOD_BROADCOM_MMC)/etc/modules.d/$(PKG_MODULE)-broadcom-mmc
+	$(INSTALL_DATA) $(WRKBUILD)/mmc.o \
+		$(IDIR_KMOD_BROADCOM_MMC)/lib/modules/$(KERNEL_VERSION)
+	$(IPKG_BUILD) $(IDIR_KMOD_BROADCOM_MMC) $(PACKAGE_DIR)

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
freewrt-developers mailing list
[email protected]
https://www.freewrt.org/lists/listinfo/freewrt-developers

Reply via email to