--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -63,6 +63,10 @@ config MTD_ROOTFS_SPLIT
 	depends on MTD_PARTITIONS
 	default y
 
+config MTD_UIMAGE_SPLIT
+	bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'"
+	default y
+
 config MTD_REDBOOT_PARTS
 	tristate "RedBoot partition table parsing"
 	depends on MTD_PARTITIONS
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -722,6 +722,82 @@ static int refresh_rootfs_split(struct m
 }
 #endif /* CONFIG_MTD_ROOTFS_SPLIT */
 
+
+#ifdef CONFIG_MTD_UIMAGE_SPLIT
+static unsigned long find_uimage_size(struct mtd_info *mtd,
+				      unsigned long offset)
+{
+#define UBOOT_MAGIC	0x56190527
+	unsigned long magic = 0;
+	unsigned long temp;
+	size_t len;
+	int ret;
+
+	ret = mtd->read(mtd, offset, 4, &len, (void *)&magic);
+	if (ret || len != sizeof(magic))
+		return 0;
+
+	if (le32_to_cpu(magic) != UBOOT_MAGIC)
+		return 0;
+
+	ret = mtd->read(mtd, offset + 12, 4, &len, (void *)&temp);
+	if (ret || len != sizeof(temp))
+		return 0;
+
+	return temp + 0x40;
+}
+
+static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
+{
+	unsigned long temp;
+	size_t len;
+	int ret;
+
+	ret = mtd->read(mtd, offset, 4, &len, (void *)&temp);
+	if (ret || len != sizeof(temp))
+		return 0;
+
+	return le32_to_cpu(temp) == SQUASHFS_MAGIC;
+}
+
+static int split_uimage(struct mtd_info *mtd,
+			const struct mtd_partition *part)
+{
+	static struct mtd_partition split_partitions[] = {
+		{
+			.name = "kernel",
+			.offset = 0x0,
+			.size = 0x0,
+		}, {
+			.name = "rootfs",
+			.offset = 0x0,
+			.size = 0x0,
+		},
+	};
+
+	split_partitions[0].size = find_uimage_size(mtd, part->offset);
+	if (!split_partitions[0].size) {
+		printk(KERN_NOTICE "no uImage found in linux partition\n");
+		return -1;
+	}
+
+	if (!detect_squashfs_partition(mtd,
+				       part->offset
+				       + split_partitions[0].size)) {
+		split_partitions[0].size &= ~(mtd->erasesize - 1);
+		split_partitions[0].size += mtd->erasesize;
+	}
+
+	split_partitions[0].offset = part->offset;
+	split_partitions[1].offset = part->offset + split_partitions[0].size;
+	split_partitions[1].size = part->size - split_partitions[0].size;
+
+	add_mtd_partitions(mtd, split_partitions, 2);
+
+	return 0;
+}
+#endif
+
 /*
  * This function, given a master MTD object and a partition table, creates
  * and registers slave MTD objects which are bound to the master according to
@@ -746,6 +822,17 @@ int add_mtd_partitions(struct mtd_info *
 		if (!slave)
 			return -ENOMEM;
 
+#ifdef CONFIG_MTD_UIMAGE_SPLIT
+		if (!strcmp(parts[i].name, "linux")) {
+			ret = split_uimage(master, &parts[i]);
+
+			if (ret) {
+				printk(KERN_WARNING
+				       "Can't split linux partition\n");
+			}
+		}
+#endif
+
 		if (!strcmp(parts[i].name, "rootfs")) {
 #ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
 			if (ROOT_DEV == 0) {