summaryrefslogtreecommitdiffstats
path: root/linux-2.4.x/drivers/mtd/chips/jedec.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-2.4.x/drivers/mtd/chips/jedec.c')
-rw-r--r--linux-2.4.x/drivers/mtd/chips/jedec.c379
1 files changed, 210 insertions, 169 deletions
diff --git a/linux-2.4.x/drivers/mtd/chips/jedec.c b/linux-2.4.x/drivers/mtd/chips/jedec.c
index b61b0ce..93efdf0 100644
--- a/linux-2.4.x/drivers/mtd/chips/jedec.c
+++ b/linux-2.4.x/drivers/mtd/chips/jedec.c
@@ -1,6 +1,6 @@
/* JEDEC Flash Interface.
- * This is an older type of interface for self programming flash. It is
+ * This is an older type of interface for self programming flash. It is
* commonly use in older AMD chips and is obsolete compared with CFI.
* It is called JEDEC because the JEDEC association distributes the ID codes
* for the chips.
@@ -11,10 +11,17 @@
* not going to guess how to send commands to them, plus I expect they will
* all speak CFI..
*
- * $Id: jedec.c,v 1.13 2002/02/08 15:57:21 rkaiser Exp $
+ * $Id: jedec.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $
*/
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/mtd/jedec.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/compatmac.h>
static struct mtd_info *jedec_probe(struct map_info *);
static int jedec_probe8(struct map_info *map,unsigned long base,
@@ -33,20 +40,57 @@ static unsigned long my_bank_size;
/* Listing of parts and sizes. We need this table to learn the sector
size of the chip and the total length */
-static const struct JEDECTable JEDEC_table[] =
- {{0x013D,"AMD Am29F017D",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
- {0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
- {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH},
- {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH},
- {0x20E3,"AMD Am29W040B",512*1024,64*1024,MTD_CAP_NORFLASH},
- {0xC2AD,"Macronix MX29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
- {}};
+static const struct JEDECTable JEDEC_table[] = {
+ {
+ .jedec = 0x013D,
+ .name = "AMD Am29F017D",
+ .size = 2*1024*1024,
+ .sectorsize = 64*1024,
+ .capabilities = MTD_CAP_NORFLASH
+ },
+ {
+ .jedec = 0x01AD,
+ .name = "AMD Am29F016",
+ .size = 2*1024*1024,
+ .sectorsize = 64*1024,
+ .capabilities = MTD_CAP_NORFLASH
+ },
+ {
+ .jedec = 0x01D5,
+ .name = "AMD Am29F080",
+ .size = 1*1024*1024,
+ .sectorsize = 64*1024,
+ .capabilities = MTD_CAP_NORFLASH
+ },
+ {
+ .jedec = 0x01A4,
+ .name = "AMD Am29F040",
+ .size = 512*1024,
+ .sectorsize = 64*1024,
+ .capabilities = MTD_CAP_NORFLASH
+ },
+ {
+ .jedec = 0x20E3,
+ .name = "AMD Am29W040B",
+ .size = 512*1024,
+ .sectorsize = 64*1024,
+ .capabilities = MTD_CAP_NORFLASH
+ },
+ {
+ .jedec = 0xC2AD,
+ .name = "Macronix MX29F016",
+ .size = 2*1024*1024,
+ .sectorsize = 64*1024,
+ .capabilities = MTD_CAP_NORFLASH
+ },
+ { .jedec = 0x0 }
+};
static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
static void jedec_sync(struct mtd_info *mtd) {};
-static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
+static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf);
-static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
+static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf);
static struct mtd_info *jedec_probe(struct map_info *map);
@@ -54,9 +98,9 @@ static struct mtd_info *jedec_probe(struct map_info *map);
static struct mtd_chip_driver jedec_chipdrv = {
- probe: jedec_probe,
- name: "jedec",
- module: THIS_MODULE
+ .probe = jedec_probe,
+ .name = "jedec",
+ .module = THIS_MODULE
};
/* Probe entry point */
@@ -78,27 +122,27 @@ static struct mtd_info *jedec_probe(struct map_info *map)
memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
priv = (struct jedec_private *)&MTD[1];
-
+
my_bank_size = map->size;
if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
{
printk("mtd: Increase MAX_JEDEC_CHIPS, too many banks.\n");
kfree(MTD);
- return 0;
+ return NULL;
}
-
+
for (Base = 0; Base < map->size; Base += my_bank_size)
{
// Perhaps zero could designate all tests?
if (map->buswidth == 0)
map->buswidth = 1;
-
+
if (map->buswidth == 1){
if (jedec_probe8(map,Base,priv) == 0) {
printk("did recognize jedec chip\n");
kfree(MTD);
- return 0;
+ return NULL;
}
}
if (map->buswidth == 2)
@@ -106,7 +150,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (map->buswidth == 4)
jedec_probe32(map,Base,priv);
}
-
+
// Get the biggest sector size
SectorSize = 0;
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
@@ -116,7 +160,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (priv->chips[I].sectorsize > SectorSize)
SectorSize = priv->chips[I].sectorsize;
}
-
+
// Quickly ensure that the other sector sizes are factors of the largest
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{
@@ -124,40 +168,39 @@ static struct mtd_info *jedec_probe(struct map_info *map)
{
printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
kfree(MTD);
- return 0;
- }
+ return NULL;
+ }
}
-
+
/* Generate a part name that includes the number of different chips and
other configuration information */
count = 1;
- strncpy(Part,map->name,sizeof(Part)-10);
- Part[sizeof(Part)-11] = 0;
+ strlcpy(Part,map->name,sizeof(Part)-10);
strcat(Part," ");
Uniq = 0;
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{
const struct JEDECTable *JEDEC;
-
+
if (priv->chips[I+1].jedec == priv->chips[I].jedec)
{
count++;
continue;
}
-
+
// Locate the chip in the jedec table
JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
if (JEDEC == 0)
{
printk("mtd: Internal Error, JEDEC not set\n");
kfree(MTD);
- return 0;
+ return NULL;
}
-
+
if (Uniq != 0)
strcat(Part,",");
Uniq++;
-
+
if (count != 1)
sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
else
@@ -165,7 +208,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (strlen(Part) > sizeof(Part)*2/3)
break;
count = 1;
- }
+ }
/* Determine if the chips are organized in a linear fashion, or if there
are empty banks. Note, the last bank does not count here, only the
@@ -179,7 +222,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (!priv->size) {
printk("priv->size is zero\n");
kfree(MTD);
- return 0;
+ return NULL;
}
if (priv->size/my_bank_size) {
if (priv->size/my_bank_size == 1) {
@@ -190,7 +233,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
{
if (priv->bank_fill[I] != my_bank_size)
priv->is_banked = 1;
-
+
/* This even could be eliminated, but new de-optimized read/write
functions have to be written */
printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
@@ -198,8 +241,8 @@ static struct mtd_info *jedec_probe(struct map_info *map)
{
printk("mtd: Failed. Cannot handle unsymmetric banking\n");
kfree(MTD);
- return 0;
- }
+ return NULL;
+ }
}
}
}
@@ -207,10 +250,9 @@ static struct mtd_info *jedec_probe(struct map_info *map)
strcat(Part,", banked");
// printk("Part: '%s'\n",Part);
-
+
memset(MTD,0,sizeof(*MTD));
- // strncpy(MTD->name,Part,sizeof(MTD->name));
- // MTD->name[sizeof(MTD->name)-1] = 0;
+ // strlcpy(MTD->name,Part,sizeof(MTD->name));
MTD->name = map->name;
MTD->type = MTD_NORFLASH;
MTD->flags = MTD_CAP_NORFLASH;
@@ -229,7 +271,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
MTD->priv = map;
map->fldrv_priv = priv;
map->fldrv = &jedec_chipdrv;
- MOD_INC_USE_COUNT;
+ __module_get(THIS_MODULE);
return MTD;
}
@@ -249,7 +291,7 @@ static int checkparity(u_char C)
/* Take an array of JEDEC numbers that represent interleved flash chips
and process them. Check to make sure they are good JEDEC numbers, look
- them up and then add them to the chip list */
+ them up and then add them to the chip list */
static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
unsigned long base,struct jedec_private *priv)
{
@@ -264,16 +306,16 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
return 0;
}
-
+
// Finally, just make sure all the chip sizes are the same
JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
-
+
if (JEDEC == 0)
{
printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
return 0;
}
-
+
Size = JEDEC->size;
SectorSize = JEDEC->sectorsize;
for (I = 0; I != Count; I++)
@@ -289,7 +331,7 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
{
printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
return 0;
- }
+ }
}
// Load the Chips
@@ -303,13 +345,13 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
{
printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
return 0;
- }
-
+ }
+
// Add them to the table
for (J = 0; J != Count; J++)
{
unsigned long Bank;
-
+
JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
priv->chips[I].size = JEDEC->size;
@@ -322,17 +364,17 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
// log2 n :|
priv->chips[I].addrshift = 0;
for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
-
+
// Determine how filled this bank is.
Bank = base & (~(my_bank_size-1));
- if (priv->bank_fill[Bank/my_bank_size] < base +
+ if (priv->bank_fill[Bank/my_bank_size] < base +
(JEDEC->size << priv->chips[I].addrshift) - Bank)
priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
I++;
}
priv->size += priv->chips[I-1].size*Count;
-
+
return priv->chips[I-1].size;
}
@@ -344,15 +386,15 @@ static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
for (I = 0; JEDEC_table[I].jedec != 0; I++)
if (JEDEC_table[I].jedec == Id)
return JEDEC_table + I;
- return 0;
+ return NULL;
}
// Look for flash using an 8 bit bus interface
static int jedec_probe8(struct map_info *map,unsigned long base,
struct jedec_private *priv)
-{
- #define flread(x) map->read8(map,base+x)
- #define flwrite(v,x) map->write8(map,v,base+x)
+{
+ #define flread(x) map_read8(map,base+x)
+ #define flwrite(v,x) map_write8(map,v,base+x)
const unsigned long AutoSel1 = 0xAA;
const unsigned long AutoSel2 = 0x55;
@@ -368,20 +410,20 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
OldVal = flread(base);
for (I = 0; OldVal != flread(base) && I < 10000; I++)
OldVal = flread(base);
-
+
// Reset the chip
- flwrite(Reset,0x555);
-
+ flwrite(Reset,0x555);
+
// Send the sequence
flwrite(AutoSel1,0x555);
flwrite(AutoSel2,0x2AA);
flwrite(AutoSel3,0x555);
-
+
// Get the JEDEC numbers
Mfg[0] = flread(0);
Id[0] = flread(1);
// printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
-
+
Size = handle_jedecs(map,Mfg,Id,1,base,priv);
// printk("handle_jedecs Size is %x\n",(unsigned int)Size);
if (Size == 0)
@@ -389,13 +431,13 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
flwrite(Reset,0x555);
return 0;
}
-
+
// Reset.
flwrite(Reset,0x555);
-
+
return 1;
-
+
#undef flread
#undef flwrite
}
@@ -411,8 +453,8 @@ static int jedec_probe16(struct map_info *map,unsigned long base,
static int jedec_probe32(struct map_info *map,unsigned long base,
struct jedec_private *priv)
{
- #define flread(x) map->read32(map,base+((x)<<2))
- #define flwrite(v,x) map->write32(map,v,base+((x)<<2))
+ #define flread(x) map_read32(map,base+((x)<<2))
+ #define flwrite(v,x) map_write32(map,v,base+((x)<<2))
const unsigned long AutoSel1 = 0xAAAAAAAA;
const unsigned long AutoSel2 = 0x55555555;
@@ -428,17 +470,17 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
OldVal = flread(base);
for (I = 0; OldVal != flread(base) && I < 10000; I++)
OldVal = flread(base);
-
+
// Reset the chip
- flwrite(Reset,0x555);
-
+ flwrite(Reset,0x555);
+
// Send the sequence
flwrite(AutoSel1,0x555);
flwrite(AutoSel2,0x2AA);
flwrite(AutoSel3,0x555);
-
+
// Test #1, JEDEC numbers are readable from 0x??00/0x??01
- if (flread(0) != flread(0x100) ||
+ if (flread(0) != flread(0x100) ||
flread(1) != flread(0x101))
{
flwrite(Reset,0x555);
@@ -452,21 +494,21 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
OldVal = flread(1);
for (I = 0; I != 4; I++)
Id[I] = (OldVal >> (I*8));
-
+
Size = handle_jedecs(map,Mfg,Id,4,base,priv);
if (Size == 0)
{
flwrite(Reset,0x555);
return 0;
}
-
+
/* Check if there is address wrap around within a single bank, if this
returns JEDEC numbers then we assume that it is wrap around. Notice
we call this routine with the JEDEC return still enabled, if two or
more flashes have a truncated address space the probe test will still
work */
- if (base + Size+0x555 < map->size &&
- base + Size+0x555 < (base & (~(my_bank_size-1))) + my_bank_size)
+ if (base + (Size<<2)+0x555 < map->size &&
+ base + (Size<<2)+0x555 < (base & (~(my_bank_size-1))) + my_bank_size)
{
if (flread(base+Size) != flread(base+Size + 0x100) ||
flread(base+Size + 1) != flread(base+Size + 0x101))
@@ -477,31 +519,31 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
// Reset.
flwrite(0xF0F0F0F0,0x555);
-
+
return 1;
-
+
#undef flread
#undef flwrite
}
/* Linear read. */
-static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
+static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
- struct map_info *map = (struct map_info *)mtd->priv;
-
- map->copy_from(map, buf, from, len);
+ struct map_info *map = mtd->priv;
+
+ map_copy_from(map, buf, from, len);
*retlen = len;
- return 0;
+ return 0;
}
/* Banked read. Take special care to jump past the holes in the bank
mapping. This version assumes symetry in the holes.. */
-static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
+static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
- struct map_info *map = (struct map_info *)mtd->priv;
- struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+ struct map_info *map = mtd->priv;
+ struct jedec_private *priv = map->fldrv_priv;
*retlen = 0;
while (len > 0)
@@ -513,17 +555,17 @@ static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
if (priv->bank_fill[0] - offset < len)
get = priv->bank_fill[0] - offset;
- bank /= priv->bank_fill[0];
- map->copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
-
+ bank /= priv->bank_fill[0];
+ map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
+
len -= get;
*retlen += get;
from += get;
- }
- return 0;
+ }
+ return 0;
}
-/* Pass the flags value that the flash return before it re-entered read
+/* Pass the flags value that the flash return before it re-entered read
mode. */
static void jedec_flash_failed(unsigned char code)
{
@@ -537,23 +579,23 @@ static void jedec_flash_failed(unsigned char code)
printk("mtd: Programming didn't take\n");
}
-/* This uses the erasure function described in the AMD Flash Handbook,
+/* This uses the erasure function described in the AMD Flash Handbook,
it will work for flashes with a fixed sector size only. Flashes with
a selection of sector sizes (ie the AMD Am29F800B) will need a different
- routine. This routine tries to parallize erasing multiple chips/sectors
+ routine. This routine tries to parallize erasing multiple chips/sectors
where possible */
static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
// Does IO to the currently selected chip
- #define flread(x) map->read8(map,chip->base+((x)<<chip->addrshift))
- #define flwrite(v,x) map->write8(map,v,chip->base+((x)<<chip->addrshift))
-
+ #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
+ #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
+
unsigned long Time = 0;
unsigned long NoTime = 0;
unsigned long start = instr->addr, len = instr->len;
unsigned int I;
- struct map_info *map = (struct map_info *)mtd->priv;
- struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+ struct map_info *map = mtd->priv;
+ struct jedec_private *priv = map->fldrv_priv;
// Verify the arguments..
if (start + len > mtd->size ||
@@ -561,7 +603,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
(len % mtd->erasesize) != 0 ||
(len/mtd->erasesize) == 0)
return -EINVAL;
-
+
jedec_flash_chip_scan(priv,start,len);
// Start the erase sequence on each chip
@@ -569,16 +611,16 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
unsigned long off;
struct jedec_flash_chip *chip = priv->chips + I;
-
+
if (chip->length == 0)
continue;
-
+
if (chip->start + chip->length > chip->size)
{
printk("DIE\n");
return -EIO;
- }
-
+ }
+
flwrite(0xF0,chip->start + 0x555);
flwrite(0xAA,chip->start + 0x555);
flwrite(0x55,chip->start + 0x2AA);
@@ -586,8 +628,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
flwrite(0xAA,chip->start + 0x555);
flwrite(0x55,chip->start + 0x2AA);
- /* Once we start selecting the erase sectors the delay between each
- command must not exceed 50us or it will immediately start erasing
+ /* Once we start selecting the erase sectors the delay between each
+ command must not exceed 50us or it will immediately start erasing
and ignore the other sectors */
for (off = 0; off < len; off += chip->sectorsize)
{
@@ -599,19 +641,19 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
printk("mtd: Ack! We timed out the erase timer!\n");
return -EIO;
- }
+ }
}
- }
+ }
/* We could split this into a timer routine and return early, performing
background erasure.. Maybe later if the need warrents */
/* Poll the flash for erasure completion, specs say this can take as long
- as 480 seconds to do all the sectors (for a 2 meg flash).
- Erasure time is dependant on chip age, temp and wear.. */
-
+ as 480 seconds to do all the sectors (for a 2 meg flash).
+ Erasure time is dependent on chip age, temp and wear.. */
+
/* This being a generic routine assumes a 32 bit bus. It does read32s
- and bundles interleved chips into the same grouping. This will work
+ and bundles interleved chips into the same grouping. This will work
for all bus widths */
Time = 0;
NoTime = 0;
@@ -622,20 +664,20 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
unsigned todo[4] = {0,0,0,0};
unsigned todo_left = 0;
unsigned J;
-
+
if (chip->length == 0)
continue;
- /* Find all chips in this data line, realistically this is all
+ /* Find all chips in this data line, realistically this is all
or nothing up to the interleve count */
for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
{
- if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
+ if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
(chip->base & (~((1<<chip->addrshift)-1))))
{
todo_left++;
todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
- }
+ }
}
/* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
@@ -645,25 +687,25 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
__u32 Last[4];
unsigned long Count = 0;
-
+
/* During erase bit 7 is held low and bit 6 toggles, we watch this,
should it stop toggling or go high then the erase is completed,
or this is not really flash ;> */
switch (map->buswidth) {
case 1:
- Last[0] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
- Last[1] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
- Last[2] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[0] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[1] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[2] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
break;
case 2:
- Last[0] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
- Last[1] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
- Last[2] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[0] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[1] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[2] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
break;
case 3:
- Last[0] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
- Last[1] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
- Last[2] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[0] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[1] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[2] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
break;
}
Count = 3;
@@ -676,40 +718,40 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
__u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
if (todo[J] == 0)
continue;
-
+
if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
{
// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
continue;
}
-
+
if (Byte1 == Byte2)
{
jedec_flash_failed(Byte3);
return -EIO;
}
-
+
todo[J] = 0;
todo_left--;
}
-
+
/* if (NoTime == 0)
Time += HZ/10 - schedule_timeout(HZ/10);*/
NoTime = 0;
switch (map->buswidth) {
case 1:
- Last[Count % 4] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[Count % 4] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
break;
case 2:
- Last[Count % 4] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[Count % 4] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
break;
case 4:
- Last[Count % 4] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
+ Last[Count % 4] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
break;
}
Count++;
-
+
/* // Count time, max of 15s per sector (according to AMD)
if (Time > 15*len/mtd->erasesize*HZ)
{
@@ -717,67 +759,66 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
return -EIO;
} */
}
-
+
// Skip to the next chip if we used chip erase
if (chip->length == chip->size)
off = chip->size;
else
off += chip->sectorsize;
-
+
if (off >= chip->length)
break;
NoTime = 1;
}
-
+
for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
{
if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
(chip->base & (~((1<<chip->addrshift)-1))))
priv->chips[J].length = 0;
- }
+ }
}
-
+
//printk("done\n");
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
-
+
#undef flread
#undef flwrite
}
/* This is the simple flash writing function. It writes to every byte, in
sequence. It takes care of how to properly address the flash if
- the flash is interleved. It can only be used if all the chips in the
+ the flash is interleved. It can only be used if all the chips in the
array are identical!*/
static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
size_t *retlen, const u_char *buf)
{
/* Does IO to the currently selected chip. It takes the bank addressing
- base (which is divisable by the chip size) adds the necesary lower bits
- of addrshift (interleve index) and then adds the control register index. */
- #define flread(x) map->read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
- #define flwrite(v,x) map->write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-
- struct map_info *map = (struct map_info *)mtd->priv;
- struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+ base (which is divisible by the chip size) adds the necessary lower bits
+ of addrshift (interleave index) and then adds the control register index. */
+ #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
+ #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
+
+ struct map_info *map = mtd->priv;
+ struct jedec_private *priv = map->fldrv_priv;
unsigned long base;
unsigned long off;
size_t save_len = len;
-
+
if (start + len > mtd->size)
return -EIO;
-
+
//printk("Here");
-
+
//printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
while (len != 0)
{
struct jedec_flash_chip *chip = priv->chips;
unsigned long bank;
unsigned long boffset;
-
+
// Compute the base of the flash.
off = ((unsigned long)start) % (chip->size << chip->addrshift);
base = start - off;
@@ -787,14 +828,14 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
boffset = base & (priv->bank_fill[0]-1);
bank = (bank/priv->bank_fill[0])*my_bank_size;
base = bank + boffset;
-
+
// printk("Flasing %X %X %X\n",base,chip->size,len);
// printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
-
+
// Loop over this page
for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
{
- unsigned char oldbyte = map->read8(map,base+off);
+ unsigned char oldbyte = map_read8(map,base+off);
unsigned char Last[4];
unsigned long Count = 0;
@@ -804,28 +845,28 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
}
if (((~oldbyte) & *buf) != 0)
printk("mtd: warn: Trying to set a 0 to a 1\n");
-
+
// Write
flwrite(0xAA,0x555);
flwrite(0x55,0x2AA);
flwrite(0xA0,0x555);
- map->write8(map,*buf,base + off);
- Last[0] = map->read8(map,base + off);
- Last[1] = map->read8(map,base + off);
- Last[2] = map->read8(map,base + off);
-
+ map_write8(map,*buf,base + off);
+ Last[0] = map_read8(map,base + off);
+ Last[1] = map_read8(map,base + off);
+ Last[2] = map_read8(map,base + off);
+
/* Wait for the flash to finish the operation. We store the last 4
status bytes that have been retrieved so we can determine why
- it failed. The toggle bits keep toggling when there is a
+ it failed. The toggle bits keep toggling when there is a
failure */
for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
Count < 10000; Count++)
- Last[Count % 4] = map->read8(map,base + off);
+ Last[Count % 4] = map_read8(map,base + off);
if (Last[(Count - 1) % 4] != *buf)
{
jedec_flash_failed(Last[(Count - 3) % 4]);
return -EIO;
- }
+ }
}
}
*retlen = save_len;
@@ -844,24 +885,24 @@ static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start
// Zero the records
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
priv->chips[I].start = priv->chips[I].length = 0;
-
+
// Intersect the region with each chip
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{
struct jedec_flash_chip *chip = priv->chips + I;
unsigned long ByteStart;
unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
-
+
// End is before this chip or the start is after it
if (start+len < chip->offset ||
ChipEndByte - (1 << chip->addrshift) < start)
continue;
-
+
if (start < chip->offset)
{
ByteStart = chip->offset;
chip->start = 0;
- }
+ }
else
{
chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;