[PATCH v2 4/6]nand/denali: Add partition support

Chuanxiao.Dong chuanxiao.dong at intel.com
Thu Aug 12 06:51:42 EDT 2010


From 8720ac9ac4313e3e0fc460a7371e2339a33d4130 Mon Sep 17 00:00:00 2001
From: Chuanxiao Dong <chuanxiao.dong at intel.com>
Date: Thu, 12 Aug 2010 18:23:59 +0800
Subject: [PATCH 4/6] nand/denali: Add partition support

In MRST platfrom, IAFW is in a protected partition which is created
by SCU FW. This partition can not be access by MTD driver. So if
did not create partitions in MRST platform, each time access the
first several blocks which is in protected partition will cause time
out.

User can pass partition info by cmdlinepart. When driver get the
partition info from command line, driver will create partitions as
command line said if the partition info is invalid(The 1st partition
must have a offset which is equal to the size of protected parition).
If there is no partition info in command line, driver will create 2
partitions as default.

This feature will not influence CE4100.

Signed-off-by: Chuanxiao Dong <chuanxiao.dong at intel.com>
---
 drivers/mtd/nand/Kconfig  |    1 +
 drivers/mtd/nand/denali.c |   75 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 6aece56..905955b 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -75,6 +75,7 @@ choice
 
 config MRST_NAND_CONTROLLER
 	bool "MRST NAND controller"
+	select MTD_PARTITIONS
 	help
 
 config CE4100_NAND_CONTROLLER
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 920c1cf..aa8f334 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -25,6 +25,7 @@
 #include <linux/pci.h>
 #include <linux/mtd/mtd.h>
 #include <linux/module.h>
+#include <linux/mtd/partitions.h>
 
 #include "denali.h"
 
@@ -1886,6 +1887,9 @@ void denali_drv_init(struct denali_nand_info *denali)
 	denali->irq_status = 0;
 }
 
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
 /* driver entry point */
 static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
@@ -1893,6 +1897,10 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	resource_size_t csr_base, mem_base;
 	unsigned long csr_len, mem_len;
 	struct denali_nand_info *denali;
+#ifdef CONFIG_MTD_PARTITIONS
+	int nr_parts;
+	struct mtd_partition *parts = NULL;
+#endif
 
 	denali = kzalloc(sizeof(*denali), GFP_KERNEL);
 	if (!denali)
@@ -2147,7 +2155,74 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 		goto failed_req_irq;
 	}
 
+#ifdef CONFIG_MTD_PARTITIONS
+	nr_parts = parse_mtd_partitions(&denali->mtd, part_probes, &parts, 0);
+	if (denali->platform == INTEL_MRST &&
+		denali->manageblks == 0) {
+		/* IAFW will manage the whole NAND, so NAND doesn't
+		 * support YAFFS2 or UBIFS file system, driver only
+		 * create one partition here to skip FW.
+		 * */
+		parts = kzalloc(sizeof(*parts), GFP_KERNEL);
+		parts->name = "Filesystem";
+		parts->offset = (uint64_t)denali->fwblks *
+						denali->mtd.erasesize;
+		parts->size = MTDPART_SIZ_FULL;
+		ret = add_mtd_partitions(&denali->mtd, parts, 1);
+		kfree(parts);
+	} else if (nr_parts >= 0 && denali->platform == INTEL_MRST) {
+		/* First check the partition information get from cmdline
+		 * For CE4100 just bypass this
+		 * For MRST, driver need to parse whether the partition
+		 * info is suit for MRST platform. If not, driver will
+		 * make adjustment
+		 * Firmware is in protected partition which
+		 * can't be accseed by MTD driver.
+		 * The blocks firmware managed contain block table
+		 * information which is needed by firmware and Spectra FTL
+		 * layer.
+		 * So here, for MRST platform, we need create at lease 2
+		 * partitions to contain Kboot and filesystem.
+		 * */
+		uint64_t offset, size;
+		offset = (uint64_t)denali->fwblks *
+			denali->mtd.erasesize;
+		size = (uint64_t)denali->manageblks *
+			denali->mtd.erasesize;
+		size -= offset;
+		if (nr_parts == 0 ||
+			parts[0].offset != offset ||
+			parts[0].size < size) {
+			dev_warn(&dev->dev,
+					"warn:invalid mtd_parts"
+					" cmdline parameters\n"
+					"please make sure the"
+					" 1st partition has:\n"
+					"offset is equal to"
+					" %lld, size larger"
+					" than %lld\n"
+					" Now use the default"
+					" partition layout",
+					offset, size);
+			parts = kzalloc(2 * sizeof(*parts), GFP_KERNEL);
+			parts[0].name = "Kboot";
+			parts[0].offset = offset;
+			parts[0].size = size;
+			parts[1].name = "Filesystem";
+			parts[1].offset = MTDPART_OFS_APPEND;
+			parts[1].size = MTDPART_SIZ_FULL;
+			ret = add_mtd_partitions(&denali->mtd, parts, 2);
+			kfree(parts);
+		} else
+			ret = add_mtd_partitions(&denali->mtd, parts, nr_parts);
+	} else if (nr_parts > 0)
+		ret = add_mtd_partitions(&denali->mtd, parts, nr_parts);
+	else
+		ret = add_mtd_partitions(&denali->mtd, parts, 1);
+#else
 	ret = add_mtd_device(&denali->mtd);
+#endif
+
 	if (ret) {
 		dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n",
 				ret);
-- 
1.6.6.1




More information about the linux-mtd mailing list