Skip to content
Snippets Groups Projects
Commit 864aa034 authored by Stefan Roese's avatar Stefan Roese Committed by Wolfgang Denk
Browse files

cmd_mtdparts: Move to common handling of FLASH devices via MTD layer


This patch removes all references to the direct CFI FLASH interface
(via flash_info[]). Now that all FLASH types currently handled in
mtdparts are available (if selected, see below) via the MTD infrastructure.
This is NOR, NAND and OneNAND right now. This can be achieved by defining
the following options:

CONFIG_MTD_DEVICE (for all FLASH types)

plus

CONFIG_FLASH_CFI_MTD (for NOR FLASH)

So we need to add those defines to the board config headers currently
using the mtdparts commands. This is done via another patch, so
we shouldn't break mtdparts compatibility.

One big advantage from this solution is that the cmd_mtdparts.c is
*much* cleaner now. Lot's of #ifdef's are removed and the code itself
is smaller. Additionally the newly added MDT concatenation feature
can new be used via the mtdparts infrastructure and therefor via
UBI etc.

Signed-off-by: default avatarStefan Roese <sr@denx.de>
Cc: Ladislav Michl <ladis@linux-mips.org>
Cc: Scott Wood <scottwood@freescale.com>
parent d558107c
No related branches found
No related tags found
No related merge requests found
...@@ -90,7 +90,8 @@ ...@@ -90,7 +90,8 @@
#include <jffs2/load_kernel.h> #include <jffs2/load_kernel.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <cramfs/cramfs_fs.h> #include <linux/err.h>
#include <linux/mtd/mtd.h>
#if defined(CONFIG_CMD_NAND) #if defined(CONFIG_CMD_NAND)
#ifdef CONFIG_NAND_LEGACY #ifdef CONFIG_NAND_LEGACY
...@@ -102,7 +103,6 @@ ...@@ -102,7 +103,6 @@
#endif #endif
#if defined(CONFIG_CMD_ONENAND) #if defined(CONFIG_CMD_ONENAND)
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h> #include <linux/mtd/onenand.h>
#include <onenand_uboot.h> #include <onenand_uboot.h>
#endif #endif
...@@ -303,137 +303,91 @@ static void current_save(void) ...@@ -303,137 +303,91 @@ static void current_save(void)
} }
/** /**
* Performs sanity check for supplied NOR flash partition. Table of existing * Performs sanity check for supplied flash partition.
* NOR flash devices is searched and partition device is located. Alignment * Table of existing MTD flash devices is searched and partition device
* with the granularity of NOR flash sectors is verified. * is located. Alignment with the granularity of nand erasesize is verified.
* *
* @param id of the parent device * @param id of the parent device
* @param part partition to validate * @param part partition to validate
* @return 0 if partition is valid, 1 otherwise * @return 0 if partition is valid, 1 otherwise
*/ */
static int part_validate_nor(struct mtdids *id, struct part_info *part) static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)
{ {
#if defined(CONFIG_CMD_FLASH) struct mtd_info *mtd;
/* info for FLASH chips */ char mtd_dev[16];
extern flash_info_t flash_info[]; int i, j;
flash_info_t *flash; ulong start;
int offset_aligned;
u32 end_offset, sector_size = 0; sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(id->type), id->num);
int i; mtd = get_mtd_device_nm(mtd_dev);
if (IS_ERR(mtd)) {
flash = &flash_info[id->num]; printf("Partition %s not found on device %s!\n", part->name, mtd_dev);
/* size of last sector */
part->sector_size = flash->size -
(flash->start[flash->sector_count-1] - flash->start[0]);
offset_aligned = 0;
for (i = 0; i < flash->sector_count; i++) {
if ((flash->start[i] - flash->start[0]) == part->offset) {
offset_aligned = 1;
break;
}
}
if (offset_aligned == 0) {
printf("%s%d: partition (%s) start offset alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name);
return 1; return 1;
} }
end_offset = part->offset + part->size; part->sector_size = mtd->erasesize;
offset_aligned = 0;
for (i = 0; i < flash->sector_count; i++) {
if (i) {
sector_size = flash->start[i] - flash->start[i-1];
if (part->sector_size < sector_size)
part->sector_size = sector_size;
}
if ((flash->start[i] - flash->start[0]) == end_offset)
offset_aligned = 1;
}
if (offset_aligned || flash->size == end_offset)
return 0;
printf("%s%d: partition (%s) size alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name);
#endif
return 1;
}
/**
* Performs sanity check for supplied NAND flash partition. Table of existing
* NAND flash devices is searched and partition device is located. Alignment
* with the granularity of nand erasesize is verified.
*
* @param id of the parent device
* @param part partition to validate
* @return 0 if partition is valid, 1 otherwise
*/
static int part_validate_nand(struct mtdids *id, struct part_info *part)
{
#if defined(CONFIG_CMD_NAND)
/* info for NAND chips */
nand_info_t *nand;
nand = &nand_info[id->num]; if (!mtd->numeraseregions) {
/*
* Only one eraseregion (NAND, OneNAND or uniform NOR),
* checking for alignment is easy here
*/
if ((unsigned long)part->offset % mtd->erasesize) {
printf("%s%d: partition (%s) start offset"
"alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name);
return 1;
}
part->sector_size = nand->erasesize; if (part->size % mtd->erasesize) {
printf("%s%d: partition (%s) size alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name);
return 1;
}
} else {
/*
* Multiple eraseregions (non-uniform NOR),
* checking for alignment is more complex here
*/
/* Check start alignment */
for (i = 0; i < mtd->numeraseregions; i++) {
start = mtd->eraseregions[i].offset;
for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
if (part->offset == start)
goto start_ok;
start += mtd->eraseregions[i].erasesize;
}
}
if ((unsigned long)(part->offset) % nand->erasesize) {
printf("%s%d: partition (%s) start offset alignment incorrect\n", printf("%s%d: partition (%s) start offset alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name); MTD_DEV_TYPE(id->type), id->num, part->name);
return 1;
}
if (part->size % nand->erasesize) {
printf("%s%d: partition (%s) size alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name);
return 1; return 1;
}
return 0; start_ok:
#else
return 1;
#endif
}
/** /* Check end/size alignment */
* Performs sanity check for supplied OneNAND flash partition. for (i = 0; i < mtd->numeraseregions; i++) {
* Table of existing OneNAND flash devices is searched and partition device start = mtd->eraseregions[i].offset;
* is located. Alignment with the granularity of nand erasesize is verified. for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
* if ((part->offset + part->size) == start)
* @param id of the parent device goto end_ok;
* @param part partition to validate start += mtd->eraseregions[i].erasesize;
* @return 0 if partition is valid, 1 otherwise }
*/ }
static int part_validate_onenand(struct mtdids *id, struct part_info *part) /* Check last sector alignment */
{ if ((part->offset + part->size) == start)
#if defined(CONFIG_CMD_ONENAND) goto end_ok;
/* info for OneNAND chips */
struct mtd_info *mtd;
mtd = &onenand_mtd;
part->sector_size = mtd->erasesize;
if ((unsigned long)(part->offset) % mtd->erasesize) {
printf("%s%d: partition (%s) start offset"
"alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name);
return 1;
}
if (part->size % mtd->erasesize) {
printf("%s%d: partition (%s) size alignment incorrect\n", printf("%s%d: partition (%s) size alignment incorrect\n",
MTD_DEV_TYPE(id->type), id->num, part->name); MTD_DEV_TYPE(id->type), id->num, part->name);
return 1; return 1;
end_ok:
return 0;
} }
return 0; return 0;
#else
return 1;
#endif
} }
...@@ -469,16 +423,11 @@ static int part_validate(struct mtdids *id, struct part_info *part) ...@@ -469,16 +423,11 @@ static int part_validate(struct mtdids *id, struct part_info *part)
return 1; return 1;
} }
if (id->type == MTD_DEV_TYPE_NAND) /*
return part_validate_nand(id, part); * Now we need to check if the partition starts and ends on
else if (id->type == MTD_DEV_TYPE_NOR) * sector (eraseblock) regions
return part_validate_nor(id, part); */
else if (id->type == MTD_DEV_TYPE_ONENAND) return part_validate_eraseblock(id, part);
return part_validate_onenand(id, part);
else
DEBUGF("part_validate: invalid dev type\n");
return 1;
} }
/** /**
...@@ -762,48 +711,19 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i ...@@ -762,48 +711,19 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
*/ */
int mtd_device_validate(u8 type, u8 num, u32 *size) int mtd_device_validate(u8 type, u8 num, u32 *size)
{ {
if (type == MTD_DEV_TYPE_NOR) { struct mtd_info *mtd;
#if defined(CONFIG_CMD_FLASH) char mtd_dev[16];
if (num < CONFIG_SYS_MAX_FLASH_BANKS) {
extern flash_info_t flash_info[];
*size = flash_info[num].size;
return 0;
}
printf("no such FLASH device: %s%d (valid range 0 ... %d\n", sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(type), num);
MTD_DEV_TYPE(type), num, CONFIG_SYS_MAX_FLASH_BANKS - 1); mtd = get_mtd_device_nm(mtd_dev);
#else if (IS_ERR(mtd)) {
printf("support for FLASH devices not present\n"); printf("Device %s not found!\n", mtd_dev);
#endif return 1;
} else if (type == MTD_DEV_TYPE_NAND) { }
#if defined(CONFIG_CMD_NAND)
if (num < CONFIG_SYS_MAX_NAND_DEVICE) {
#ifndef CONFIG_NAND_LEGACY
*size = nand_info[num].size;
#else
extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE];
*size = nand_dev_desc[num].totlen;
#endif
return 0;
}
printf("no such NAND device: %s%d (valid range 0 ... %d)\n", *size = mtd->size;
MTD_DEV_TYPE(type), num, CONFIG_SYS_MAX_NAND_DEVICE - 1);
#else
printf("support for NAND devices not present\n");
#endif
} else if (type == MTD_DEV_TYPE_ONENAND) {
#if defined(CONFIG_CMD_ONENAND)
*size = onenand_mtd.size;
return 0;
#else
printf("support for OneNAND devices not present\n");
#endif
} else
printf("Unknown defice type %d\n", type);
return 1; return 0;
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment