diff -aur kernel-source-2.6.16.old/drivers/mmc/mmc.c kernel-source-2.6.16/drivers/mmc/mmc.c
--- kernel-source-2.6.16.old/drivers/mmc/mmc.c	2006-06-20 16:01:59.000000000 +0200
+++ kernel-source-2.6.16/drivers/mmc/mmc.c	2006-10-03 10:33:43.000000000 +0200
@@ -369,6 +369,20 @@
 		}
 	}
 
+	/* Activate highspeed MMC v4 support. */
+	if (card->csd.mmca_vsn == 4) {
+		struct mmc_command cmd;
+		cmd.opcode = SD_APP_SET_BUS_WIDTH;
+	 	cmd.arg = 0x03B90100;
+		cmd.flags = MMC_RSP_R1B;
+
+		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
+		if (err != MMC_ERR_NONE)
+			return err;
+		mmc_card_set_highspeed(card);
+	}
+
+
 	host->ops->set_ios(host, &host->ios);
 
 	return MMC_ERR_NONE;
@@ -893,6 +907,88 @@
 	}
 }
 
+static void mmc_read_ext_csds(struct mmc_host *host)
+{
+	int err;
+	struct mmc_card *card;
+
+	struct mmc_request mrq;
+	struct mmc_command cmd;
+	struct mmc_data data;
+
+	struct scatterlist sg;
+
+	/*
+	 * As the ext_csd is so large and mostly unused, we don't store the
+	 * raw block in mmc_card.
+	 */
+	u8 ext_csd[512];
+
+	list_for_each_entry(card, &host->cards, node) {
+		if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
+			continue;
+		if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
+			continue;
+
+		err = mmc_select_card(host, card);
+		if (err != MMC_ERR_NONE) {
+			mmc_card_set_dead(card);
+			continue;
+		}
+
+		memset(&cmd, 0, sizeof(struct mmc_command));
+
+		cmd.opcode = MMC_SEND_EXT_CSD;
+		cmd.arg = 0;
+		cmd.flags = MMC_RSP_R1;
+
+		memset(&data, 0, sizeof(struct mmc_data));
+
+		data.timeout_ns = card->csd.tacc_ns * 10;
+		data.timeout_clks = card->csd.tacc_clks * 10;
+		data.blksz_bits = 9;
+		data.blocks = 1;
+		data.flags = MMC_DATA_READ;
+		data.sg = &sg;
+		data.sg_len = 1;
+
+		memset(&mrq, 0, sizeof(struct mmc_request));
+
+		mrq.cmd = &cmd;
+		mrq.data = &data;
+
+		sg_init_one(&sg, &ext_csd, 512);
+
+		mmc_wait_for_req(host, &mrq);
+
+		if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
+			mmc_card_set_dead(card);
+			continue;
+		}
+
+		card->ext_csd.cmd_set_rev = ext_csd[EXT_CSD_CMD_SET_REV];
+		card->ext_csd.ext_csd_rev = ext_csd[EXT_CSD_EXT_CSD_REV];
+		card->ext_csd.csd_structure = ext_csd[EXT_CSD_CSD_STRUCTURE];
+		card->ext_csd.card_type = ext_csd[EXT_CSD_CARD_TYPE];
+
+		card->ext_csd.pwr_cl_52_195 = ext_csd[EXT_CSD_PWR_CL_52_195];
+		card->ext_csd.pwr_cl_26_195 = ext_csd[EXT_CSD_PWR_CL_26_195];
+		card->ext_csd.pwr_cl_52_360 = ext_csd[EXT_CSD_PWR_CL_52_360];
+		card->ext_csd.pwr_cl_26_360 = ext_csd[EXT_CSD_PWR_CL_26_360];
+
+		card->ext_csd.min_perf_r_4_26 = ext_csd[EXT_CSD_MIN_PERF_R_4_26];
+		card->ext_csd.min_perf_w_4_26 = ext_csd[EXT_CSD_MIN_PERF_W_4_26];
+		card->ext_csd.min_perf_r_8_26_4_52 = ext_csd[EXT_CSD_MIN_PERF_R_8_26_4_52];
+		card->ext_csd.min_perf_w_8_26_4_52 = ext_csd[EXT_CSD_MIN_PERF_W_8_26_4_52];
+		card->ext_csd.min_perf_r_8_52 = ext_csd[EXT_CSD_MIN_PERF_R_8_52];
+		card->ext_csd.min_perf_w_8_52 = ext_csd[EXT_CSD_MIN_PERF_W_8_52];
+
+		card->ext_csd.s_cmd_set = ext_csd[EXT_CSD_S_CMD_SET];
+	}
+
+	mmc_deselect_cards(host);
+}
+
 static void mmc_read_scrs(struct mmc_host *host)
 {
 	int err;
@@ -973,8 +1069,20 @@
 	unsigned int max_dtr = host->f_max;
 
 	list_for_each_entry(card, &host->cards, node)
-		if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr)
-			max_dtr = card->csd.max_dtr;
+		if (!mmc_card_dead(card) ) {
+			unsigned int card_dtr = card->csd.max_dtr;
+			if (card->csd.mmca_vsn == 4 && mmc_card_highspeed(card)) {
+			/* card support it and highspeed mode is enabled */ 
+				if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_26 ){
+					card_dtr = 26000000;
+				}
+				if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_52 ){
+					card_dtr = 52000000;
+				}
+			}
+			if (max_dtr > card_dtr)
+				max_dtr=card_dtr;
+		}
 
 	DBG("MMC: selected %d.%03dMHz transfer rate\n",
 	    max_dtr / 1000000, (max_dtr / 1000) % 1000);
@@ -1101,6 +1209,8 @@
 
 	if (host->mode == MMC_MODE_SD)
 		mmc_read_scrs(host);
+	else
+		mmc_read_ext_csds(host);
 }
 
 
diff -aur kernel-source-2.6.16.old/drivers/mmc/mmc_block.c kernel-source-2.6.16/drivers/mmc/mmc_block.c
--- kernel-source-2.6.16.old/drivers/mmc/mmc_block.c	2006-06-20 16:01:59.000000000 +0200
+++ kernel-source-2.6.16/drivers/mmc/mmc_block.c	2006-10-03 10:20:43.000000000 +0200
@@ -330,6 +330,7 @@
 	 */
 	md->read_only = mmc_blk_readonly(card);
 
+#if 0
 	/*
 	 * Figure out a workable block size.  MMC cards have:
 	 *  - two block sizes, one for read and one for write.
@@ -367,7 +368,15 @@
 			md->read_only = 1;
 		}
 	}
+#endif
+	md->block_bits = 9; /* hardcode block size to 512, cards >=2GB need this, others don't mind */
+	printk(KERN_INFO "card reports rb%u wb%u rp%u wp%u, we set rb,wb to 512\n",
+				1 << card->csd.read_blkbits,
+				1 << card->csd.write_blkbits,
+				card->csd.read_partial,
+				card->csd.write_partial);
 
+#if 0	 
 	/*
 	 * Refuse to allow block sizes smaller than 512 bytes.
 	 */
@@ -377,7 +386,7 @@
 		ret = -EINVAL;
 		goto err_kfree;
 	}
-
+#endif
 	md->disk = alloc_disk(1 << MMC_SHIFT);
 	if (md->disk == NULL) {
 		ret = -ENOMEM;
diff -aur kernel-source-2.6.16.old/drivers/mmc/omap.c kernel-source-2.6.16/drivers/mmc/omap.c
--- kernel-source-2.6.16.old/drivers/mmc/omap.c	2006-06-20 16:01:59.000000000 +0200
+++ kernel-source-2.6.16/drivers/mmc/omap.c	2006-09-30 14:01:34.000000000 +0200
@@ -159,14 +159,14 @@
 	u32 cmdreg;
 	u32 resptype;
 	u32 cmdtype;
-
+#if 0
 	pr_debug("MMC%d: CMD%d, argument 0x%08x%s%s%s%s\n",
 		host->id, cmd->opcode, cmd->arg,
 		(cmd->flags & MMC_RSP_SHORT) ?  ", 32-bit response" : "",
 		(cmd->flags & MMC_RSP_LONG) ?  ", 128-bit response" : "",
 		(cmd->flags & MMC_RSP_CRC) ?  ", CRC" : "",
 		(cmd->flags & MMC_RSP_BUSY) ?  ", busy notification" : "");
-
+#endif
 	host->cmd = cmd;
 
 	resptype = 0;
@@ -1152,7 +1152,8 @@
 
 		if (dsor > 250)
 			dsor = 250;
-		dsor++;
+// why?		dsor++;
+	DBG("MMC%d: set_ios: requested %dHz, divisor %d -> real clock %dHz\n",host->id,realclock,dsor,(func_clk_rate / dsor));
 
 		if (ios->bus_width == MMC_BUS_WIDTH_4)
 			dsor |= 1 << 15;
@@ -1288,7 +1289,7 @@
 
 	mmc->ops = &mmc_omap_ops;
 	mmc->f_min = 400000;
-	mmc->f_max = 24000000;
+	mmc->f_max = 48000000;
 	mmc->ocr_avail = MMC_VDD_33_34;
 
 	/* Use scatterlist DMA to reduce per-transfer costs.
diff -aur kernel-source-2.6.16.old/include/linux/mmc/card.h kernel-source-2.6.16/include/linux/mmc/card.h
--- kernel-source-2.6.16.old/include/linux/mmc/card.h	2006-06-20 16:02:02.000000000 +0200
+++ kernel-source-2.6.16/include/linux/mmc/card.h	2006-10-02 17:44:09.000000000 +0200
@@ -38,6 +38,48 @@
 				write_misalign:1;
 };
 
+struct mmc_ext_csd {
+	unsigned char		cmd_set_rev;
+	unsigned char		ext_csd_rev;
+	unsigned char		csd_structure;
+
+	unsigned char		card_type;
+
+	/*
+	 * Each power class defines MAX RMS Current
+	 * and Max Peak Current in mA.
+	 * Each category is of the form:
+	 *   pwr_cl_<speed/MHz>_<voltage/V>
+	 *
+	 * Each category encodes the power class for 4
+	 * bit transfers in [3:0] and 8 bit transfers
+	 * in [7:4]. Use mmc_get_4bit_pwr_cl() and
+	 * mmc_get_8bit_pwr_cl() to decode these.
+	 */
+	unsigned char		pwr_cl_52_195;
+	unsigned char		pwr_cl_26_195;
+
+	unsigned char		pwr_cl_52_360;
+	unsigned char		pwr_cl_26_360;
+
+	/*
+	 * Performance classes describe the minimum
+	 * transfer speed the card claims to support
+	 * for the given bus widths and speeds.
+	 */
+	unsigned char		min_perf_r_4_26;
+	unsigned char		min_perf_w_4_26;
+	unsigned char		min_perf_r_8_26_4_52;
+	unsigned char		min_perf_w_8_26_4_52;
+	unsigned char		min_perf_r_8_52;
+	unsigned char		min_perf_w_8_52;
+
+	unsigned char		s_cmd_set;
+};
+
+#define mmc_get_4bit_pwr_cl(p)	(p & 0x0F)
+#define mmc_get_8bit_pwr_cl(p)	(p >> 4)
+
 struct sd_scr {
 	unsigned char		sda_vsn;
 	unsigned char		bus_widths;
@@ -61,11 +103,13 @@
 #define MMC_STATE_BAD		(1<<2)		/* unrecognised device */
 #define MMC_STATE_SDCARD	(1<<3)		/* is an SD card */
 #define MMC_STATE_READONLY	(1<<4)		/* card is read-only */
+#define MMC_STATE_HIGHSPEED	(1<<5)		/* card is in mmc4 highspeed mode */
 	u32			raw_cid[4];	/* raw card CID */
 	u32			raw_csd[4];	/* raw card CSD */
 	u32			raw_scr[2];	/* raw card SCR */
 	struct mmc_cid		cid;		/* card identification */
 	struct mmc_csd		csd;		/* card specific */
+	struct mmc_ext_csd	ext_csd;	/* mmc v4 extended card specific */
 	struct sd_scr		scr;		/* extra SD information */
 };
 
@@ -74,12 +118,14 @@
 #define mmc_card_bad(c)		((c)->state & MMC_STATE_BAD)
 #define mmc_card_sd(c)		((c)->state & MMC_STATE_SDCARD)
 #define mmc_card_readonly(c)	((c)->state & MMC_STATE_READONLY)
+#define mmc_card_highspeed(c)	((c)->state & MMC_STATE_HIGHSPEED)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_dead(c)	((c)->state |= MMC_STATE_DEAD)
 #define mmc_card_set_bad(c)	((c)->state |= MMC_STATE_BAD)
 #define mmc_card_set_sd(c)	((c)->state |= MMC_STATE_SDCARD)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
+#define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED)
 
 #define mmc_card_name(c)	((c)->cid.prod_name)
 #define mmc_card_id(c)		((c)->dev.bus_id)
diff -aur kernel-source-2.6.16.old/include/linux/mmc/protocol.h kernel-source-2.6.16/include/linux/mmc/protocol.h
--- kernel-source-2.6.16.old/include/linux/mmc/protocol.h	2006-06-20 16:02:02.000000000 +0200
+++ kernel-source-2.6.16/include/linux/mmc/protocol.h	2006-10-02 17:48:32.000000000 +0200
@@ -33,6 +33,7 @@
 #define MMC_SET_RELATIVE_ADDR     3   /* ac   [31:16] RCA        R1  */
 #define MMC_SET_DSR               4   /* bc   [31:16] RCA            */
 #define MMC_SELECT_CARD           7   /* ac   [31:16] RCA        R1  */
+#define MMC_SEND_EXT_CSD          8   /* adtc                    R1  */
 #define MMC_SEND_CSD              9   /* ac   [31:16] RCA        R2  */
 #define MMC_SEND_CID             10   /* ac   [31:16] RCA        R2  */
 #define MMC_READ_DAT_UNTIL_STOP  11   /* adtc [31:0] dadr        R1  */
@@ -235,6 +236,99 @@
 #define CSD_SPEC_VER_1      1           /* Implements system specification 1.4 */
 #define CSD_SPEC_VER_2      2           /* Implements system specification 2.0 - 2.2 */
 #define CSD_SPEC_VER_3      3           /* Implements system specification 3.1 */
+#define CSD_SPEC_VER_4      4           /* Implements system specification 4.0 - 4.1 */
+/*
+ * EXT_CSD fields
+ */
+#define EXT_CSD_BUS_WIDTH		183	/* WO  */
+#define EXT_CSD_HS_TIMING		185	/* R/W */
+#define EXT_CSD_POWER_CLASS		187	/* R/W */
+#define EXT_CSD_CMD_SET_REV		189	/* RO  */
+#define EXT_CSD_CMD_SET		191	/* R/W */
+#define EXT_CSD_EXT_CSD_REV		192	/* RO  */
+#define EXT_CSD_CSD_STRUCTURE		194	/* RO  */
+#define EXT_CSD_CARD_TYPE		196	/* RO  */
+#define EXT_CSD_PWR_CL_52_195		200	/* RO  */
+#define EXT_CSD_PWR_CL_26_195		201	/* RO  */
+#define EXT_CSD_PWR_CL_52_360		202	/* RO  */
+#define EXT_CSD_PWR_CL_26_360		203	/* RO  */
+#define EXT_CSD_MIN_PERF_R_4_26	205	/* RO  */
+#define EXT_CSD_MIN_PERF_W_4_26	206	/* RO  */
+#define EXT_CSD_MIN_PERF_R_8_26_4_52	207	/* RO  */
+#define EXT_CSD_MIN_PERF_W_8_26_4_52	208	/* RO  */
+#define EXT_CSD_MIN_PERF_R_8_52	209	/* RO  */
+#define EXT_CSD_MIN_PERF_W_8_52	210	/* RO  */
+#define EXT_CSD_S_CMD_SET		504	/* RO  */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_BUS_WIDTH_1     0
+#define EXT_CSD_BUS_WIDTH_4     1
+#define EXT_CSD_BUS_WIDTH_8     2
+
+#define EXT_CSD_HS_TIMING_LEGACY	0	/* <= 20MHz */
+#define EXT_CSD_HS_TIMING_FAST		1	/* > 20Mhz */
+
+#define EXT_CSD_CMD_SET_REV_4	0
+
+#define EXT_CSD_CMD_SET_NORMAL		(1<<0)
+#define EXT_CSD_CMD_SET_SECURE		(1<<1)
+#define EXT_CSD_CMD_SET_CPSECURE	(1<<2)
+
+#define EXT_CSD_EXT_CSD_REV_1_0	0
+#define EXT_CSD_EXT_CSD_REV_1_1	1
+
+#define EXT_CSD_CARD_TYPE_26	(1<<0)	/* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52	(1<<1)	/* Card can run at 52MHz */
+
+/*
+ * Power classes
+ *
+ * Each class is of the form:
+ *   <voltage>_<max RMS current/mA>_<max Peak Current/mA>
+ *
+ */
+#define EXT_CSD_PWR_CL_195_065_130	0
+#define EXT_CSD_PWR_CL_195_070_140	1
+#define EXT_CSD_PWR_CL_195_080_160	2
+#define EXT_CSD_PWR_CL_195_090_180	3
+#define EXT_CSD_PWR_CL_195_100_200	4
+#define EXT_CSD_PWR_CL_195_120_220	5
+#define EXT_CSD_PWR_CL_195_140_240	6
+#define EXT_CSD_PWR_CL_195_160_260	7
+#define EXT_CSD_PWR_CL_195_180_280	8
+#define EXT_CSD_PWR_CL_195_200_300	9
+#define EXT_CSD_PWR_CL_195_250_350	10
+
+#define EXT_CSD_PWR_CL_360_100_200	0
+#define EXT_CSD_PWR_CL_360_120_220	1
+#define EXT_CSD_PWR_CL_360_150_250	2
+#define EXT_CSD_PWR_CL_360_180_280	3
+#define EXT_CSD_PWR_CL_360_200_300	4
+#define EXT_CSD_PWR_CL_360_220_320	5
+#define EXT_CSD_PWR_CL_360_250_350	6
+#define EXT_CSD_PWR_CL_360_300_400	7
+#define EXT_CSD_PWR_CL_360_350_450	8
+#define EXT_CSD_PWR_CL_360_400_500	9
+#define EXT_CSD_PWR_CL_360_450_550	10
+
+#define EXT_CSD_MIN_PERF_CLASS_LEGACY	0x00 /* < 2.4 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_A	0x08 /* 2.4 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_B	0x0A /* 3 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_C	0x0F /* 4.5 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_D	0x14 /* 6 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_E	0x1E /* 9 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_F	0x28 /* 12 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_G	0x32 /* 15 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_H	0x3C /* 18 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_J	0x46 /* 21 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_K	0x50 /* 24 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_M	0x64 /* 30 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_O	0x78 /* 36 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_R	0x8C /* 42 MB/s */
+#define EXT_CSD_MIN_PERF_CLASS_T	0xA0 /* 48 MB/s */
 
 
 /*
