[MTD] chips: Clean up trailing white spaces

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Thomas Gleixner 2005-11-07 11:15:37 +00:00 committed by Thomas Gleixner
parent e4f0648fb4
commit 1f948b43f7
15 changed files with 493 additions and 493 deletions

View File

@ -1,5 +1,5 @@
# drivers/mtd/chips/Kconfig # drivers/mtd/chips/Kconfig
# $Id: Kconfig,v 1.15 2005/06/06 23:04:35 tpoynor Exp $ # $Id: Kconfig,v 1.18 2005/11/07 11:14:22 gleixner Exp $
menu "RAM/ROM/Flash chip drivers" menu "RAM/ROM/Flash chip drivers"
depends on MTD!=n depends on MTD!=n
@ -39,7 +39,7 @@ config MTD_CFI_ADV_OPTIONS
If you need to specify a specific endianness for access to flash If you need to specify a specific endianness for access to flash
chips, or if you wish to reduce the size of the kernel by including chips, or if you wish to reduce the size of the kernel by including
support for only specific arrangements of flash chips, say 'Y'. This support for only specific arrangements of flash chips, say 'Y'. This
option does not directly affect the code, but will enable other option does not directly affect the code, but will enable other
configuration options which allow you to do so. configuration options which allow you to do so.
If unsure, say 'N'. If unsure, say 'N'.
@ -56,7 +56,7 @@ config MTD_CFI_NOSWAP
data bits when writing the 'magic' commands to the chips. Saying data bits when writing the 'magic' commands to the chips. Saying
'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't 'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't
enabled, means that the CPU will not do any swapping; the chips enabled, means that the CPU will not do any swapping; the chips
are expected to be wired to the CPU in 'host-endian' form. are expected to be wired to the CPU in 'host-endian' form.
Specific arrangements are possible with the BIG_ENDIAN_BYTE and Specific arrangements are possible with the BIG_ENDIAN_BYTE and
LITTLE_ENDIAN_BYTE, if the bytes are reversed. LITTLE_ENDIAN_BYTE, if the bytes are reversed.
@ -79,10 +79,10 @@ config MTD_CFI_GEOMETRY
bool "Specific CFI Flash geometry selection" bool "Specific CFI Flash geometry selection"
depends on MTD_CFI_ADV_OPTIONS depends on MTD_CFI_ADV_OPTIONS
help help
This option does not affect the code directly, but will enable This option does not affect the code directly, but will enable
some other configuration options which would allow you to reduce some other configuration options which would allow you to reduce
the size of the kernel by including support for only certain the size of the kernel by including support for only certain
arrangements of CFI chips. If unsure, say 'N' and all options arrangements of CFI chips. If unsure, say 'N' and all options
which are supported by the current code will be enabled. which are supported by the current code will be enabled.
config MTD_MAP_BANK_WIDTH_1 config MTD_MAP_BANK_WIDTH_1
@ -197,7 +197,7 @@ config MTD_CFI_AMDSTD
help help
The Common Flash Interface defines a number of different command The Common Flash Interface defines a number of different command
sets which a CFI-compliant chip may claim to implement. This code sets which a CFI-compliant chip may claim to implement. This code
provides support for one of those command sets, used on chips provides support for one of those command sets, used on chips
including the AMD Am29LV320. including the AMD Am29LV320.
config MTD_CFI_AMDSTD_RETRY config MTD_CFI_AMDSTD_RETRY
@ -237,14 +237,14 @@ config MTD_RAM
tristate "Support for RAM chips in bus mapping" tristate "Support for RAM chips in bus mapping"
depends on MTD depends on MTD
help help
This option enables basic support for RAM chips accessed through This option enables basic support for RAM chips accessed through
a bus mapping driver. a bus mapping driver.
config MTD_ROM config MTD_ROM
tristate "Support for ROM chips in bus mapping" tristate "Support for ROM chips in bus mapping"
depends on MTD depends on MTD
help help
This option enables basic support for ROM chips accessed through This option enables basic support for ROM chips accessed through
a bus mapping driver. a bus mapping driver.
config MTD_ABSENT config MTD_ABSENT
@ -275,7 +275,7 @@ config MTD_AMDSTD
depends on MTD && MTD_OBSOLETE_CHIPS depends on MTD && MTD_OBSOLETE_CHIPS
help help
This option enables support for flash chips using AMD-compatible This option enables support for flash chips using AMD-compatible
commands, including some which are not CFI-compatible and hence commands, including some which are not CFI-compatible and hence
cannot be used with the CONFIG_MTD_CFI_AMDSTD option. cannot be used with the CONFIG_MTD_CFI_AMDSTD option.
It also works on AMD compatible chips that do conform to CFI. It also works on AMD compatible chips that do conform to CFI.
@ -285,7 +285,7 @@ config MTD_SHARP
depends on MTD && MTD_OBSOLETE_CHIPS depends on MTD && MTD_OBSOLETE_CHIPS
help help
This option enables support for flash chips using Sharp-compatible This option enables support for flash chips using Sharp-compatible
commands, including some which are not CFI-compatible and hence commands, including some which are not CFI-compatible and hence
cannot be used with the CONFIG_MTD_CFI_INTELxxx options. cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
config MTD_JEDEC config MTD_JEDEC

View File

@ -1,7 +1,7 @@
# #
# linux/drivers/chips/Makefile # linux/drivers/chips/Makefile
# #
# $Id: Makefile.common,v 1.4 2004/07/12 16:07:30 dwmw2 Exp $ # $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
# *** BIG UGLY NOTE *** # *** BIG UGLY NOTE ***
# #
@ -11,7 +11,7 @@
# the CFI command set drivers are linked before gen_probe.o # the CFI command set drivers are linked before gen_probe.o
obj-$(CONFIG_MTD) += chipreg.o obj-$(CONFIG_MTD) += chipreg.o
obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
obj-$(CONFIG_MTD_CFI) += cfi_probe.o obj-$(CONFIG_MTD_CFI) += cfi_probe.o
obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o

View File

@ -3,7 +3,7 @@
* *
* Author: Jonas Holmberg <jonas.holmberg@axis.com> * Author: Jonas Holmberg <jonas.holmberg@axis.com>
* *
* $Id: amd_flash.c,v 1.27 2005/02/04 07:43:09 jonashg Exp $ * $Id: amd_flash.c,v 1.28 2005/11/07 11:14:22 gleixner Exp $
* *
* Copyright (c) 2001 Axis Communications AB * Copyright (c) 2001 Axis Communications AB
* *
@ -93,9 +93,9 @@
#define D6_MASK 0x40 #define D6_MASK 0x40
struct amd_flash_private { struct amd_flash_private {
int device_type; int device_type;
int interleave; int interleave;
int numchips; int numchips;
unsigned long chipshift; unsigned long chipshift;
// const char *im_name; // const char *im_name;
struct flchip chips[0]; struct flchip chips[0];
@ -253,7 +253,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
int i; int i;
int retval = 0; int retval = 0;
int lock_status; int lock_status;
map = mtd->priv; map = mtd->priv;
/* Pass the whole chip through sector by sector and check for each /* Pass the whole chip through sector by sector and check for each
@ -273,7 +273,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
unlock_sector(map, eraseoffset, is_unlock); unlock_sector(map, eraseoffset, is_unlock);
lock_status = is_sector_locked(map, eraseoffset); lock_status = is_sector_locked(map, eraseoffset);
if (is_unlock && lock_status) { if (is_unlock && lock_status) {
printk("Cannot unlock sector at address %x length %xx\n", printk("Cannot unlock sector at address %x length %xx\n",
eraseoffset, merip->erasesize); eraseoffset, merip->erasesize);
@ -305,7 +305,7 @@ static int amd_flash_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
/* /*
* Reads JEDEC manufacturer ID and device ID and returns the index of the first * Reads JEDEC manufacturer ID and device ID and returns the index of the first
* matching table entry (-1 if not found or alias for already found chip). * matching table entry (-1 if not found or alias for already found chip).
*/ */
static int probe_new_chip(struct mtd_info *mtd, __u32 base, static int probe_new_chip(struct mtd_info *mtd, __u32 base,
struct flchip *chips, struct flchip *chips,
struct amd_flash_private *private, struct amd_flash_private *private,
@ -636,7 +636,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
{ .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 } { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 }
} }
} }
}; };
struct mtd_info *mtd; struct mtd_info *mtd;
@ -701,7 +701,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
mtd->numeraseregions, GFP_KERNEL); mtd->numeraseregions, GFP_KERNEL);
if (!mtd->eraseregions) { if (!mtd->eraseregions) {
printk(KERN_WARNING "%s: Failed to allocate " printk(KERN_WARNING "%s: Failed to allocate "
"memory for MTD erase region info\n", map->name); "memory for MTD erase region info\n", map->name);
kfree(mtd); kfree(mtd);
@ -739,12 +739,12 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
mtd->type = MTD_NORFLASH; mtd->type = MTD_NORFLASH;
mtd->flags = MTD_CAP_NORFLASH; mtd->flags = MTD_CAP_NORFLASH;
mtd->name = map->name; mtd->name = map->name;
mtd->erase = amd_flash_erase; mtd->erase = amd_flash_erase;
mtd->read = amd_flash_read; mtd->read = amd_flash_read;
mtd->write = amd_flash_write; mtd->write = amd_flash_write;
mtd->sync = amd_flash_sync; mtd->sync = amd_flash_sync;
mtd->suspend = amd_flash_suspend; mtd->suspend = amd_flash_suspend;
mtd->resume = amd_flash_resume; mtd->resume = amd_flash_resume;
mtd->lock = amd_flash_lock; mtd->lock = amd_flash_lock;
mtd->unlock = amd_flash_unlock; mtd->unlock = amd_flash_unlock;
@ -789,7 +789,7 @@ retry:
map->name, chip->state); map->name, chip->state);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule(); schedule();
@ -802,7 +802,7 @@ retry:
timeo = jiffies + HZ; timeo = jiffies + HZ;
goto retry; goto retry;
} }
adr += chip->start; adr += chip->start;
@ -889,7 +889,7 @@ retry:
map->name, chip->state); map->name, chip->state);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule(); schedule();
@ -901,7 +901,7 @@ retry:
timeo = jiffies + HZ; timeo = jiffies + HZ;
goto retry; goto retry;
} }
chip->state = FL_WRITING; chip->state = FL_WRITING;
@ -911,7 +911,7 @@ retry:
wide_write(map, datum, adr); wide_write(map, datum, adr);
times_left = 500000; times_left = 500000;
while (times_left-- && flash_is_busy(map, adr, private->interleave)) { while (times_left-- && flash_is_busy(map, adr, private->interleave)) {
if (need_resched()) { if (need_resched()) {
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule(); schedule();
@ -989,7 +989,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
if (ret) { if (ret) {
return ret; return ret;
} }
ofs += n; ofs += n;
buf += n; buf += n;
(*retlen) += n; (*retlen) += n;
@ -1002,7 +1002,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
} }
} }
} }
/* We are now aligned, write as much as possible. */ /* We are now aligned, write as much as possible. */
while(len >= map->buswidth) { while(len >= map->buswidth) {
__u32 datum; __u32 datum;
@ -1063,7 +1063,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
if (ret) { if (ret) {
return ret; return ret;
} }
(*retlen) += n; (*retlen) += n;
} }
@ -1085,7 +1085,7 @@ retry:
if (chip->state != FL_READY){ if (chip->state != FL_READY){
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule(); schedule();
@ -1098,7 +1098,7 @@ retry:
timeo = jiffies + HZ; timeo = jiffies + HZ;
goto retry; goto retry;
} }
chip->state = FL_ERASING; chip->state = FL_ERASING;
@ -1106,30 +1106,30 @@ retry:
ENABLE_VPP(map); ENABLE_VPP(map);
send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA); send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA);
send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr); send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr);
timeo = jiffies + (HZ * 20); timeo = jiffies + (HZ * 20);
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
msleep(1000); msleep(1000);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
while (flash_is_busy(map, adr, private->interleave)) { while (flash_is_busy(map, adr, private->interleave)) {
if (chip->state != FL_ERASING) { if (chip->state != FL_ERASING) {
/* Someone's suspended the erase. Sleep */ /* Someone's suspended the erase. Sleep */
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
printk(KERN_INFO "%s: erase suspended. Sleeping\n", printk(KERN_INFO "%s: erase suspended. Sleeping\n",
map->name); map->name);
schedule(); schedule();
remove_wait_queue(&chip->wq, &wait); remove_wait_queue(&chip->wq, &wait);
if (signal_pending(current)) { if (signal_pending(current)) {
return -EINTR; return -EINTR;
} }
timeo = jiffies + (HZ*2); /* FIXME */ timeo = jiffies + (HZ*2); /* FIXME */
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
continue; continue;
@ -1145,7 +1145,7 @@ retry:
return -EIO; return -EIO;
} }
/* Latency issues. Drop the lock, wait a while and retry */ /* Latency issues. Drop the lock, wait a while and retry */
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
@ -1153,7 +1153,7 @@ retry:
schedule(); schedule();
else else
udelay(1); udelay(1);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
} }
@ -1180,7 +1180,7 @@ retry:
return -EIO; return -EIO;
} }
} }
DISABLE_VPP(map); DISABLE_VPP(map);
chip->state = FL_READY; chip->state = FL_READY;
wake_up(&chip->wq); wake_up(&chip->wq);
@ -1246,7 +1246,7 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
* with the erase region at that address. * with the erase region at that address.
*/ */
while ((i < mtd->numeraseregions) && while ((i < mtd->numeraseregions) &&
((instr->addr + instr->len) >= regions[i].offset)) { ((instr->addr + instr->len) >= regions[i].offset)) {
i++; i++;
} }
@ -1293,10 +1293,10 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
} }
} }
} }
instr->state = MTD_ERASE_DONE; instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr); mtd_erase_callback(instr);
return 0; return 0;
} }
@ -1324,7 +1324,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
case FL_JEDEC_QUERY: case FL_JEDEC_QUERY:
chip->oldstate = chip->state; chip->oldstate = chip->state;
chip->state = FL_SYNCING; chip->state = FL_SYNCING;
/* No need to wake_up() on this state change - /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything * as the whole point is that nobody can do anything
* with the chip now anyway. * with the chip now anyway.
*/ */
@ -1335,13 +1335,13 @@ static void amd_flash_sync(struct mtd_info *mtd)
default: default:
/* Not an idle state */ /* Not an idle state */
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule(); schedule();
remove_wait_queue(&chip->wq, &wait); remove_wait_queue(&chip->wq, &wait);
goto retry; goto retry;
} }
} }
@ -1351,7 +1351,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
chip = &private->chips[i]; chip = &private->chips[i];
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
if (chip->state == FL_SYNCING) { if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate; chip->state = chip->oldstate;
wake_up(&chip->wq); wake_up(&chip->wq);

View File

@ -4,9 +4,9 @@
* *
* (C) 2000 Red Hat. GPL'd * (C) 2000 Red Hat. GPL'd
* *
* $Id: cfi_cmdset_0001.c,v 1.184 2005/10/25 20:28:40 nico Exp $ * $Id: cfi_cmdset_0001.c,v 1.185 2005/11/07 11:14:22 gleixner Exp $
*
* *
*
* 10/10/2000 Nicolas Pitre <nico@cam.org> * 10/10/2000 Nicolas Pitre <nico@cam.org>
* - completely revamped method functions so they are aware and * - completely revamped method functions so they are aware and
* independent of the flash geometry (buswidth, interleave, etc.) * independent of the flash geometry (buswidth, interleave, etc.)
@ -120,17 +120,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported");
printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported"); printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported");
for (i=11; i<32; i++) { for (i=11; i<32; i++) {
if (extp->FeatureSupport & (1<<i)) if (extp->FeatureSupport & (1<<i))
printk(" - Unknown Bit %X: supported\n", i); printk(" - Unknown Bit %X: supported\n", i);
} }
printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
for (i=1; i<8; i++) { for (i=1; i<8; i++) {
if (extp->SuspendCmdSupport & (1<<i)) if (extp->SuspendCmdSupport & (1<<i))
printk(" - Unknown Bit %X: supported\n", i); printk(" - Unknown Bit %X: supported\n", i);
} }
printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
@ -145,16 +145,16 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
printk(" - Unknown Bit %X Active: yes\n",i); printk(" - Unknown Bit %X Active: yes\n",i);
} }
printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
extp->VccOptimal >> 4, extp->VccOptimal & 0xf); extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
if (extp->VppOptimal) if (extp->VppOptimal)
printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
extp->VppOptimal >> 4, extp->VppOptimal & 0xf); extp->VppOptimal >> 4, extp->VppOptimal & 0xf);
} }
#endif #endif
#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
{ {
struct map_info *map = mtd->priv; struct map_info *map = mtd->priv;
@ -185,7 +185,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
{ {
struct map_info *map = mtd->priv; struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */
cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
} }
@ -194,7 +194,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
{ {
struct map_info *map = mtd->priv; struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
/* Note this is done after the region info is endian swapped */ /* Note this is done after the region info is endian swapped */
cfi->cfiq->EraseRegionInfo[1] = cfi->cfiq->EraseRegionInfo[1] =
(cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
@ -222,7 +222,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
static struct cfi_fixup cfi_fixup_table[] = { static struct cfi_fixup cfi_fixup_table[] = {
#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
#endif #endif
#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL },
@ -327,7 +327,7 @@ read_pri_intelext(struct map_info *map, __u16 adr)
goto again; goto again;
} }
} }
return extp; return extp;
} }
@ -368,7 +368,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
if (cfi->cfi_mode == CFI_MODE_CFI) { if (cfi->cfi_mode == CFI_MODE_CFI) {
/* /*
* It's a real CFI chip, not one for which the probe * It's a real CFI chip, not one for which the probe
* routine faked a CFI structure. So we read the feature * routine faked a CFI structure. So we read the feature
* table from it. * table from it.
@ -383,14 +383,14 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
} }
/* Install our own private info structure */ /* Install our own private info structure */
cfi->cmdset_priv = extp; cfi->cmdset_priv = extp;
cfi_fixup(mtd, cfi_fixup_table); cfi_fixup(mtd, cfi_fixup_table);
#ifdef DEBUG_CFI_FEATURES #ifdef DEBUG_CFI_FEATURES
/* Tell the user about it in lots of lovely detail */ /* Tell the user about it in lots of lovely detail */
cfi_tell_features(extp); cfi_tell_features(extp);
#endif #endif
if(extp->SuspendCmdSupport & 1) { if(extp->SuspendCmdSupport & 1) {
printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n");
@ -408,10 +408,10 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
cfi->chips[i].ref_point_counter = 0; cfi->chips[i].ref_point_counter = 0;
} }
map->fldrv = &cfi_intelext_chipdrv; map->fldrv = &cfi_intelext_chipdrv;
return cfi_intelext_setup(mtd); return cfi_intelext_setup(mtd);
} }
@ -428,13 +428,13 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
mtd->size = devsize * cfi->numchips; mtd->size = devsize * cfi->numchips;
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
* mtd->numeraseregions, GFP_KERNEL); * mtd->numeraseregions, GFP_KERNEL);
if (!mtd->eraseregions) { if (!mtd->eraseregions) {
printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
goto setup_err; goto setup_err;
} }
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
unsigned long ernum, ersize; unsigned long ernum, ersize;
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@ -701,7 +701,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
break; break;
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n", printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n",
map->name, status.x[0]); map->name, status.x[0]);
return -EIO; return -EIO;
} }
@ -711,7 +711,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
/* Someone else might have been playing with it. */ /* Someone else might have been playing with it. */
goto retry; goto retry;
} }
case FL_READY: case FL_READY:
case FL_CFI_QUERY: case FL_CFI_QUERY:
case FL_JEDEC_QUERY: case FL_JEDEC_QUERY:
@ -830,14 +830,14 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
switch(chip->oldstate) { switch(chip->oldstate) {
case FL_ERASING: case FL_ERASING:
chip->state = chip->oldstate; chip->state = chip->oldstate;
/* What if one interleaved chip has finished and the /* What if one interleaved chip has finished and the
other hasn't? The old code would leave the finished other hasn't? The old code would leave the finished
one in READY mode. That's bad, and caused -EROFS one in READY mode. That's bad, and caused -EROFS
errors to be returned from do_erase_oneblock because errors to be returned from do_erase_oneblock because
that's the only bit it checked for at the time. that's the only bit it checked for at the time.
As the state machine appears to explicitly allow As the state machine appears to explicitly allow
sending the 0x70 (Read Status) command to an erasing sending the 0x70 (Read Status) command to an erasing
chip and expecting it to be ignored, that's what we chip and expecting it to be ignored, that's what we
do. */ do. */
map_write(map, CMD(0xd0), adr); map_write(map, CMD(0xd0), adr);
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
@ -1073,8 +1073,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
adr += chip->start; adr += chip->start;
/* Ensure cmd read/writes are aligned. */ /* Ensure cmd read/writes are aligned. */
cmd_addr = adr & ~(map_bankwidth(map)-1); cmd_addr = adr & ~(map_bankwidth(map)-1);
spin_lock(chip->mutex); spin_lock(chip->mutex);
@ -1102,7 +1102,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
if (!map->virt || (from + len > mtd->size)) if (!map->virt || (from + len > mtd->size))
return -EINVAL; return -EINVAL;
*mtdbuf = (void *)map->virt + from; *mtdbuf = (void *)map->virt + from;
*retlen = 0; *retlen = 0;
@ -1129,7 +1129,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
*retlen += thislen; *retlen += thislen;
len -= thislen; len -= thislen;
ofs = 0; ofs = 0;
chipnum++; chipnum++;
} }
@ -1187,8 +1187,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
adr += chip->start; adr += chip->start;
/* Ensure cmd read/writes are aligned. */ /* Ensure cmd read/writes are aligned. */
cmd_addr = adr & ~(map_bankwidth(map)-1); cmd_addr = adr & ~(map_bankwidth(map)-1);
spin_lock(chip->mutex); spin_lock(chip->mutex);
ret = get_chip(map, chip, cmd_addr, FL_READY); ret = get_chip(map, chip, cmd_addr, FL_READY);
@ -1243,7 +1243,7 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz
*retlen += thislen; *retlen += thislen;
len -= thislen; len -= thislen;
buf += thislen; buf += thislen;
ofs = 0; ofs = 0;
chipnum++; chipnum++;
} }
@ -1311,7 +1311,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* OK Still waiting */ /* OK Still waiting */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
@ -1331,7 +1331,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
if (!chip->word_write_time) if (!chip->word_write_time)
chip->word_write_time = 1; chip->word_write_time = 1;
} }
if (z > 1) if (z > 1)
chip->word_write_time++; chip->word_write_time++;
/* Done and happy. */ /* Done and happy. */
@ -1394,7 +1394,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
ret = do_write_oneword(map, &cfi->chips[chipnum], ret = do_write_oneword(map, &cfi->chips[chipnum],
bus_ofs, datum, FL_WRITING); bus_ofs, datum, FL_WRITING);
if (ret) if (ret)
return ret; return ret;
len -= n; len -= n;
@ -1403,13 +1403,13 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
(*retlen) += n; (*retlen) += n;
if (ofs >> cfi->chipshift) { if (ofs >> cfi->chipshift) {
chipnum ++; chipnum ++;
ofs = 0; ofs = 0;
if (chipnum == cfi->numchips) if (chipnum == cfi->numchips)
return 0; return 0;
} }
} }
while(len >= map_bankwidth(map)) { while(len >= map_bankwidth(map)) {
map_word datum = map_word_load(map, buf); map_word datum = map_word_load(map, buf);
@ -1424,7 +1424,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
len -= map_bankwidth(map); len -= map_bankwidth(map);
if (ofs >> cfi->chipshift) { if (ofs >> cfi->chipshift) {
chipnum ++; chipnum ++;
ofs = 0; ofs = 0;
if (chipnum == cfi->numchips) if (chipnum == cfi->numchips)
return 0; return 0;
@ -1439,9 +1439,9 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
ret = do_write_oneword(map, &cfi->chips[chipnum], ret = do_write_oneword(map, &cfi->chips[chipnum],
ofs, datum, FL_WRITING); ofs, datum, FL_WRITING);
if (ret) if (ret)
return ret; return ret;
(*retlen) += len; (*retlen) += len;
} }
@ -1449,7 +1449,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
} }
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long adr, const struct kvec **pvec, unsigned long adr, const struct kvec **pvec,
unsigned long *pvec_seek, int len) unsigned long *pvec_seek, int len)
{ {
@ -1480,7 +1480,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
xip_disable(map, chip, cmd_adr); xip_disable(map, chip, cmd_adr);
/* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
[...], the device will not accept any more Write to Buffer commands". [...], the device will not accept any more Write to Buffer commands".
So we must check here and reset those bits if they're set. Otherwise So we must check here and reset those bits if they're set. Otherwise
we're just pissing in the wind */ we're just pissing in the wind */
if (chip->state != FL_STATUS) if (chip->state != FL_STATUS)
@ -1549,9 +1549,9 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
if (!word_gap && len < map_bankwidth(map)) if (!word_gap && len < map_bankwidth(map))
datum = map_word_ff(map); datum = map_word_ff(map);
datum = map_word_load_partial(map, datum, datum = map_word_load_partial(map, datum,
vec->iov_base + vec_seek, vec->iov_base + vec_seek,
word_gap, n); word_gap, n);
len -= n; len -= n;
@ -1575,7 +1575,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
map_write(map, CMD(0xd0), cmd_adr); map_write(map, CMD(0xd0), cmd_adr);
chip->state = FL_WRITING; chip->state = FL_WRITING;
INVALIDATE_CACHE_UDELAY(map, chip, INVALIDATE_CACHE_UDELAY(map, chip,
cmd_adr, len, cmd_adr, len,
chip->buffer_write_time); chip->buffer_write_time);
@ -1608,7 +1608,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
/* Latency issues. Drop the lock, wait a while and retry */ /* Latency issues. Drop the lock, wait a while and retry */
z++; z++;
UDELAY(map, chip, cmd_adr, 1); UDELAY(map, chip, cmd_adr, 1);
@ -1618,7 +1618,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
if (!chip->buffer_write_time) if (!chip->buffer_write_time)
chip->buffer_write_time = 1; chip->buffer_write_time = 1;
} }
if (z > 1) if (z > 1)
chip->buffer_write_time++; chip->buffer_write_time++;
/* Done and happy. */ /* Done and happy. */
@ -1680,7 +1680,7 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
if (size > len) if (size > len)
size = len; size = len;
ret = do_write_buffer(map, &cfi->chips[chipnum], ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, &vecs, &vec_seek, size); ofs, &vecs, &vec_seek, size);
if (ret) if (ret)
return ret; return ret;
@ -1690,7 +1690,7 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
len -= size; len -= size;
if (ofs >> cfi->chipshift) { if (ofs >> cfi->chipshift) {
chipnum ++; chipnum ++;
ofs = 0; ofs = 0;
if (chipnum == cfi->numchips) if (chipnum == cfi->numchips)
return 0; return 0;
@ -1776,7 +1776,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* OK Still waiting */ /* OK Still waiting */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
@ -1786,7 +1786,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
/* Latency issues. Drop the lock, wait a while and retry */ /* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1000000/HZ); UDELAY(map, chip, adr, 1000000/HZ);
} }
@ -1849,7 +1849,7 @@ int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE; instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr); mtd_erase_callback(instr);
return 0; return 0;
} }
@ -1870,7 +1870,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
if (!ret) { if (!ret) {
chip->oldstate = chip->state; chip->oldstate = chip->state;
chip->state = FL_SYNCING; chip->state = FL_SYNCING;
/* No need to wake_up() on this state change - /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything * as the whole point is that nobody can do anything
* with the chip now anyway. * with the chip now anyway.
*/ */
@ -1884,7 +1884,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock(chip->mutex); spin_lock(chip->mutex);
if (chip->state == FL_SYNCING) { if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate; chip->state = chip->oldstate;
chip->oldstate = FL_READY; chip->oldstate = FL_READY;
@ -1941,7 +1941,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
ENABLE_VPP(map); ENABLE_VPP(map);
xip_disable(map, chip, adr); xip_disable(map, chip, adr);
map_write(map, CMD(0x60), adr); map_write(map, CMD(0x60), adr);
if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
map_write(map, CMD(0x01), adr); map_write(map, CMD(0x01), adr);
@ -1969,7 +1969,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* OK Still waiting */ /* OK Still waiting */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
@ -1980,11 +1980,11 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
return -EIO; return -EIO;
} }
/* Latency issues. Drop the lock, wait a while and retry */ /* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1); UDELAY(map, chip, adr, 1);
} }
/* Done and happy. */ /* Done and happy. */
chip->state = FL_STATUS; chip->state = FL_STATUS;
xip_enable(map, chip, adr); xip_enable(map, chip, adr);
@ -2004,9 +2004,9 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
ofs, len, 0); ofs, len, 0);
#endif #endif
ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); ofs, len, DO_XXLOCK_ONEBLOCK_LOCK);
#ifdef DEBUG_LOCK_BITS #ifdef DEBUG_LOCK_BITS
printk(KERN_DEBUG "%s: lock status after, ret=%d\n", printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
__FUNCTION__, ret); __FUNCTION__, ret);
@ -2030,20 +2030,20 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK);
#ifdef DEBUG_LOCK_BITS #ifdef DEBUG_LOCK_BITS
printk(KERN_DEBUG "%s: lock status after, ret=%d\n", printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
__FUNCTION__, ret); __FUNCTION__, ret);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock, cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
ofs, len, 0); ofs, len, 0);
#endif #endif
return ret; return ret;
} }
#ifdef CONFIG_MTD_OTP #ifdef CONFIG_MTD_OTP
typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
u_long data_offset, u_char *buf, u_int size, u_long data_offset, u_char *buf, u_int size,
u_long prot_offset, u_int groupno, u_int groupsize); u_long prot_offset, u_int groupno, u_int groupsize);
@ -2094,7 +2094,7 @@ do_otp_write(struct map_info *map, struct flchip *chip, u_long offset,
datum = map_word_load_partial(map, datum, buf, gap, n); datum = map_word_load_partial(map, datum, buf, gap, n);
ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE); ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE);
if (ret) if (ret)
return ret; return ret;
offset += n; offset += n;
@ -2287,7 +2287,7 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
NULL, do_otp_lock, 1); NULL, do_otp_lock, 1);
} }
static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
struct otp_info *buf, size_t len) struct otp_info *buf, size_t len)
{ {
size_t retlen; size_t retlen;
@ -2330,7 +2330,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
if (chip->oldstate == FL_READY) { if (chip->oldstate == FL_READY) {
chip->oldstate = chip->state; chip->oldstate = chip->state;
chip->state = FL_PM_SUSPENDED; chip->state = FL_PM_SUSPENDED;
/* No need to wake_up() on this state change - /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything * as the whole point is that nobody can do anything
* with the chip now anyway. * with the chip now anyway.
*/ */
@ -2358,9 +2358,9 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
if (ret) { if (ret) {
for (i--; i >=0; i--) { for (i--; i >=0; i--) {
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock(chip->mutex); spin_lock(chip->mutex);
if (chip->state == FL_PM_SUSPENDED) { if (chip->state == FL_PM_SUSPENDED) {
/* No need to force it into a known state here, /* No need to force it into a known state here,
because we're returning failure, and it didn't because we're returning failure, and it didn't
@ -2371,8 +2371,8 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
} }
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
} }
} }
return ret; return ret;
} }
@ -2384,11 +2384,11 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
struct flchip *chip; struct flchip *chip;
for (i=0; i<cfi->numchips; i++) { for (i=0; i<cfi->numchips; i++) {
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock(chip->mutex); spin_lock(chip->mutex);
/* Go to known state. Chip may have been power cycled */ /* Go to known state. Chip may have been power cycled */
if (chip->state == FL_PM_SUSPENDED) { if (chip->state == FL_PM_SUSPENDED) {
map_write(map, CMD(0xFF), cfi->chips[i].start); map_write(map, CMD(0xFF), cfi->chips[i].start);
@ -2410,7 +2410,7 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
struct flchip *chip = &cfi->chips[i]; struct flchip *chip = &cfi->chips[i];
/* force the completion of any ongoing operation /* force the completion of any ongoing operation
and switch to array mode so any bootloader in and switch to array mode so any bootloader in
flash is accessible for soft reboot. */ flash is accessible for soft reboot. */
spin_lock(chip->mutex); spin_lock(chip->mutex);
ret = get_chip(map, chip, chip->start, FL_SYNCING); ret = get_chip(map, chip, chip->start, FL_SYNCING);

View File

@ -10,14 +10,14 @@
* *
* 4_by_16 work by Carolyn J. Smith * 4_by_16 work by Carolyn J. Smith
* *
* XIP support hooks by Vitaly Wool (based on code for Intel flash * XIP support hooks by Vitaly Wool (based on code for Intel flash
* by Nicolas Pitre) * by Nicolas Pitre)
* *
* Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
* *
* This code is GPL * This code is GPL
* *
* $Id: cfi_cmdset_0002.c,v 1.121 2005/11/07 09:00:01 gleixner Exp $ * $Id: cfi_cmdset_0002.c,v 1.122 2005/11/07 11:14:22 gleixner Exp $
* *
*/ */
@ -93,7 +93,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
}; };
printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1); printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1);
printk(" Address sensitive unlock: %s\n", printk(" Address sensitive unlock: %s\n",
(extp->SiliconRevision & 1) ? "Not required" : "Required"); (extp->SiliconRevision & 1) ? "Not required" : "Required");
if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend)) if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend))
@ -118,9 +118,9 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
else else
printk(" Page mode: %d word page\n", extp->PageMode << 2); printk(" Page mode: %d word page\n", extp->PageMode << 2);
printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n", printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
extp->VppMin >> 4, extp->VppMin & 0xf); extp->VppMin >> 4, extp->VppMin & 0xf);
printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n", printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
extp->VppMax >> 4, extp->VppMax & 0xf); extp->VppMax >> 4, extp->VppMax & 0xf);
if (extp->TopBottom < ARRAY_SIZE(top_bottom)) if (extp->TopBottom < ARRAY_SIZE(top_bottom))
@ -177,7 +177,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) { ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) {
mtd->erase = cfi_amdstd_erase_chip; mtd->erase = cfi_amdstd_erase_chip;
} }
} }
static struct cfi_fixup cfi_fixup_table[] = { static struct cfi_fixup cfi_fixup_table[] = {
@ -239,7 +239,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
if (cfi->cfi_mode==CFI_MODE_CFI){ if (cfi->cfi_mode==CFI_MODE_CFI){
unsigned char bootloc; unsigned char bootloc;
/* /*
* It's a real CFI chip, not one for which the probe * It's a real CFI chip, not one for which the probe
* routine faked a CFI structure. So we read the feature * routine faked a CFI structure. So we read the feature
* table from it. * table from it.
@ -264,7 +264,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
} }
/* Install our own private info structure */ /* Install our own private info structure */
cfi->cmdset_priv = extp; cfi->cmdset_priv = extp;
/* Apply cfi device specific fixups */ /* Apply cfi device specific fixups */
cfi_fixup(mtd, cfi_fixup_table); cfi_fixup(mtd, cfi_fixup_table);
@ -272,7 +272,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
#ifdef DEBUG_CFI_FEATURES #ifdef DEBUG_CFI_FEATURES
/* Tell the user about it in lots of lovely detail */ /* Tell the user about it in lots of lovely detail */
cfi_tell_features(extp); cfi_tell_features(extp);
#endif #endif
bootloc = extp->TopBottom; bootloc = extp->TopBottom;
if ((bootloc != 2) && (bootloc != 3)) { if ((bootloc != 2) && (bootloc != 3)) {
@ -283,11 +283,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name); printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) { for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
int j = (cfi->cfiq->NumEraseRegions-1)-i; int j = (cfi->cfiq->NumEraseRegions-1)-i;
__u32 swap; __u32 swap;
swap = cfi->cfiq->EraseRegionInfo[i]; swap = cfi->cfiq->EraseRegionInfo[i];
cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
cfi->cfiq->EraseRegionInfo[j] = swap; cfi->cfiq->EraseRegionInfo[j] = swap;
@ -298,11 +298,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
cfi->addr_unlock2 = 0x2aa; cfi->addr_unlock2 = 0x2aa;
/* Modify the unlock address if we are in compatibility mode */ /* Modify the unlock address if we are in compatibility mode */
if ( /* x16 in x8 mode */ if ( /* x16 in x8 mode */
((cfi->device_type == CFI_DEVICETYPE_X8) && ((cfi->device_type == CFI_DEVICETYPE_X8) &&
(cfi->cfiq->InterfaceDesc == 2)) || (cfi->cfiq->InterfaceDesc == 2)) ||
/* x32 in x16 mode */ /* x32 in x16 mode */
((cfi->device_type == CFI_DEVICETYPE_X16) && ((cfi->device_type == CFI_DEVICETYPE_X16) &&
(cfi->cfiq->InterfaceDesc == 4))) (cfi->cfiq->InterfaceDesc == 4)))
{ {
cfi->addr_unlock1 = 0xaaa; cfi->addr_unlock1 = 0xaaa;
cfi->addr_unlock2 = 0x555; cfi->addr_unlock2 = 0x555;
@ -320,10 +320,10 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
} }
map->fldrv = &cfi_amdstd_chipdrv; map->fldrv = &cfi_amdstd_chipdrv;
return cfi_amdstd_setup(mtd); return cfi_amdstd_setup(mtd);
} }
@ -336,24 +336,24 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
unsigned long offset = 0; unsigned long offset = 0;
int i,j; int i,j;
printk(KERN_NOTICE "number of %s chips: %d\n", printk(KERN_NOTICE "number of %s chips: %d\n",
(cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
/* Select the correct geometry setup */ /* Select the correct geometry setup */
mtd->size = devsize * cfi->numchips; mtd->size = devsize * cfi->numchips;
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
* mtd->numeraseregions, GFP_KERNEL); * mtd->numeraseregions, GFP_KERNEL);
if (!mtd->eraseregions) { if (!mtd->eraseregions) {
printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
goto setup_err; goto setup_err;
} }
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
unsigned long ernum, ersize; unsigned long ernum, ersize;
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
if (mtd->erasesize < ersize) { if (mtd->erasesize < ersize) {
mtd->erasesize = ersize; mtd->erasesize = ersize;
} }
@ -440,7 +440,7 @@ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word
oldd = map_read(map, addr); oldd = map_read(map, addr);
curd = map_read(map, addr); curd = map_read(map, addr);
return map_word_equal(map, oldd, curd) && return map_word_equal(map, oldd, curd) &&
map_word_equal(map, curd, expected); map_word_equal(map, curd, expected);
} }
@ -472,7 +472,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
/* Someone else might have been playing with it. */ /* Someone else might have been playing with it. */
goto retry; goto retry;
} }
case FL_READY: case FL_READY:
case FL_CFI_QUERY: case FL_CFI_QUERY:
case FL_JEDEC_QUERY: case FL_JEDEC_QUERY:
@ -515,7 +515,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
return -EIO; return -EIO;
} }
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
cfi_udelay(1); cfi_udelay(1);
spin_lock(chip->mutex); spin_lock(chip->mutex);
@ -618,7 +618,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
* When a delay is required for the flash operation to complete, the * When a delay is required for the flash operation to complete, the
* xip_udelay() function is polling for both the given timeout and pending * xip_udelay() function is polling for both the given timeout and pending
* (but still masked) hardware interrupts. Whenever there is an interrupt * (but still masked) hardware interrupts. Whenever there is an interrupt
* pending then the flash erase operation is suspended, array mode restored * pending then the flash erase operation is suspended, array mode restored
* and interrupts unmasked. Task scheduling might also happen at that * and interrupts unmasked. Task scheduling might also happen at that
* point. The CPU eventually returns from the interrupt or the call to * point. The CPU eventually returns from the interrupt or the call to
* schedule() and the suspended flash operation is resumed for the remaining * schedule() and the suspended flash operation is resumed for the remaining
@ -642,9 +642,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) && ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
(cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
/* /*
* Let's suspend the erase operation when supported. * Let's suspend the erase operation when supported.
* Note that we currently don't try to suspend * Note that we currently don't try to suspend
* interleaved chips if there is already another * interleaved chips if there is already another
* operation suspended (imagine what happens * operation suspended (imagine what happens
* when one chip was already done with the current * when one chip was already done with the current
* operation while another chip suspended it, then * operation while another chip suspended it, then
@ -780,8 +780,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
adr += chip->start; adr += chip->start;
/* Ensure cmd read/writes are aligned. */ /* Ensure cmd read/writes are aligned. */
cmd_addr = adr & ~(map_bankwidth(map)-1); cmd_addr = adr & ~(map_bankwidth(map)-1);
spin_lock(chip->mutex); spin_lock(chip->mutex);
ret = get_chip(map, chip, cmd_addr, FL_READY); ret = get_chip(map, chip, cmd_addr, FL_READY);
@ -861,7 +861,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
#endif #endif
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
schedule(); schedule();
@ -873,7 +873,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
timeo = jiffies + HZ; timeo = jiffies + HZ;
goto retry; goto retry;
} }
adr += chip->start; adr += chip->start;
@ -882,14 +882,14 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
map_copy_from(map, buf, adr, len); map_copy_from(map, buf, adr, len);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
wake_up(&chip->wq); wake_up(&chip->wq);
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
@ -998,7 +998,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
chip->word_write_time); chip->word_write_time);
/* See comment above for timeout value. */ /* See comment above for timeout value. */
timeo = jiffies + uWriteTimeout; timeo = jiffies + uWriteTimeout;
for (;;) { for (;;) {
if (chip->state != FL_WRITING) { if (chip->state != FL_WRITING) {
/* Someone's suspended the write. Sleep */ /* Someone's suspended the write. Sleep */
@ -1033,7 +1033,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
map_write( map, CMD(0xF0), chip->start ); map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */ /* FIXME - should have reset delay before continuing */
if (++retry_cnt <= MAX_WORD_RETRIES) if (++retry_cnt <= MAX_WORD_RETRIES)
goto retry; goto retry;
ret = -EIO; ret = -EIO;
@ -1101,27 +1101,27 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
/* Number of bytes to copy from buffer */ /* Number of bytes to copy from buffer */
n = min_t(int, len, map_bankwidth(map)-i); n = min_t(int, len, map_bankwidth(map)-i);
tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n); tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n);
ret = do_write_oneword(map, &cfi->chips[chipnum], ret = do_write_oneword(map, &cfi->chips[chipnum],
bus_ofs, tmp_buf); bus_ofs, tmp_buf);
if (ret) if (ret)
return ret; return ret;
ofs += n; ofs += n;
buf += n; buf += n;
(*retlen) += n; (*retlen) += n;
len -= n; len -= n;
if (ofs >> cfi->chipshift) { if (ofs >> cfi->chipshift) {
chipnum ++; chipnum ++;
ofs = 0; ofs = 0;
if (chipnum == cfi->numchips) if (chipnum == cfi->numchips)
return 0; return 0;
} }
} }
/* We are now aligned, write as much as possible */ /* We are now aligned, write as much as possible */
while(len >= map_bankwidth(map)) { while(len >= map_bankwidth(map)) {
map_word datum; map_word datum;
@ -1139,7 +1139,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
len -= map_bankwidth(map); len -= map_bankwidth(map);
if (ofs >> cfi->chipshift) { if (ofs >> cfi->chipshift) {
chipnum ++; chipnum ++;
ofs = 0; ofs = 0;
if (chipnum == cfi->numchips) if (chipnum == cfi->numchips)
return 0; return 0;
@ -1177,12 +1177,12 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
spin_unlock(cfi->chips[chipnum].mutex); spin_unlock(cfi->chips[chipnum].mutex);
tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
ret = do_write_oneword(map, &cfi->chips[chipnum], ret = do_write_oneword(map, &cfi->chips[chipnum],
ofs, tmp_buf); ofs, tmp_buf);
if (ret) if (ret)
return ret; return ret;
(*retlen) += len; (*retlen) += len;
} }
@ -1194,7 +1194,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
* FIXME: interleaved mode not tested, and probably not supported! * FIXME: interleaved mode not tested, and probably not supported!
*/ */
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long adr, const u_char *buf, unsigned long adr, const u_char *buf,
int len) int len)
{ {
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
@ -1224,7 +1224,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
XIP_INVAL_CACHED_RANGE(map, adr, len); XIP_INVAL_CACHED_RANGE(map, adr, len);
ENABLE_VPP(map); ENABLE_VPP(map);
xip_disable(map, chip, cmd_adr); xip_disable(map, chip, cmd_adr);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
//cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@ -1258,8 +1258,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
adr, map_bankwidth(map), adr, map_bankwidth(map),
chip->word_write_time); chip->word_write_time);
timeo = jiffies + uWriteTimeout; timeo = jiffies + uWriteTimeout;
for (;;) { for (;;) {
if (chip->state != FL_WRITING) { if (chip->state != FL_WRITING) {
/* Someone's suspended the write. Sleep */ /* Someone's suspended the write. Sleep */
@ -1353,7 +1353,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
if (size % map_bankwidth(map)) if (size % map_bankwidth(map))
size -= size % map_bankwidth(map); size -= size % map_bankwidth(map);
ret = do_write_buffer(map, &cfi->chips[chipnum], ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, buf, size); ofs, buf, size);
if (ret) if (ret)
return ret; return ret;
@ -1364,7 +1364,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
len -= size; len -= size;
if (ofs >> cfi->chipshift) { if (ofs >> cfi->chipshift) {
chipnum ++; chipnum ++;
ofs = 0; ofs = 0;
if (chipnum == cfi->numchips) if (chipnum == cfi->numchips)
return 0; return 0;
@ -1581,7 +1581,7 @@ int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE; instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr); mtd_erase_callback(instr);
return 0; return 0;
} }
@ -1604,7 +1604,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE; instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr); mtd_erase_callback(instr);
return 0; return 0;
} }
@ -1631,7 +1631,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
case FL_JEDEC_QUERY: case FL_JEDEC_QUERY:
chip->oldstate = chip->state; chip->oldstate = chip->state;
chip->state = FL_SYNCING; chip->state = FL_SYNCING;
/* No need to wake_up() on this state change - /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything * as the whole point is that nobody can do anything
* with the chip now anyway. * with the chip now anyway.
*/ */
@ -1642,13 +1642,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
default: default:
/* Not an idle state */ /* Not an idle state */
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
schedule(); schedule();
remove_wait_queue(&chip->wq, &wait); remove_wait_queue(&chip->wq, &wait);
goto retry; goto retry;
} }
} }
@ -1659,7 +1659,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock(chip->mutex); spin_lock(chip->mutex);
if (chip->state == FL_SYNCING) { if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate; chip->state = chip->oldstate;
wake_up(&chip->wq); wake_up(&chip->wq);
@ -1689,7 +1689,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
case FL_JEDEC_QUERY: case FL_JEDEC_QUERY:
chip->oldstate = chip->state; chip->oldstate = chip->state;
chip->state = FL_PM_SUSPENDED; chip->state = FL_PM_SUSPENDED;
/* No need to wake_up() on this state change - /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything * as the whole point is that nobody can do anything
* with the chip now anyway. * with the chip now anyway.
*/ */
@ -1710,7 +1710,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock(chip->mutex); spin_lock(chip->mutex);
if (chip->state == FL_PM_SUSPENDED) { if (chip->state == FL_PM_SUSPENDED) {
chip->state = chip->oldstate; chip->state = chip->oldstate;
wake_up(&chip->wq); wake_up(&chip->wq);
@ -1718,7 +1718,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
} }
} }
return ret; return ret;
} }
@ -1731,11 +1731,11 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
struct flchip *chip; struct flchip *chip;
for (i=0; i<cfi->numchips; i++) { for (i=0; i<cfi->numchips; i++) {
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock(chip->mutex); spin_lock(chip->mutex);
if (chip->state == FL_PM_SUSPENDED) { if (chip->state == FL_PM_SUSPENDED) {
chip->state = FL_READY; chip->state = FL_READY;
map_write(map, CMD(0xF0), chip->start); map_write(map, CMD(0xF0), chip->start);

View File

@ -4,7 +4,7 @@
* *
* (C) 2000 Red Hat. GPL'd * (C) 2000 Red Hat. GPL'd
* *
* $Id: cfi_cmdset_0020.c,v 1.20 2005/07/20 21:01:14 tpoynor Exp $ * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $
* *
* 10/10/2000 Nicolas Pitre <nico@cam.org> * 10/10/2000 Nicolas Pitre <nico@cam.org>
* - completely revamped method functions so they are aware and * - completely revamped method functions so they are aware and
@ -81,17 +81,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
for (i=9; i<32; i++) { for (i=9; i<32; i++) {
if (extp->FeatureSupport & (1<<i)) if (extp->FeatureSupport & (1<<i))
printk(" - Unknown Bit %X: supported\n", i); printk(" - Unknown Bit %X: supported\n", i);
} }
printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
for (i=1; i<8; i++) { for (i=1; i<8; i++) {
if (extp->SuspendCmdSupport & (1<<i)) if (extp->SuspendCmdSupport & (1<<i))
printk(" - Unknown Bit %X: supported\n", i); printk(" - Unknown Bit %X: supported\n", i);
} }
printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
@ -99,11 +99,11 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
if (extp->BlkStatusRegMask & (1<<i)) if (extp->BlkStatusRegMask & (1<<i))
printk(" - Unknown Bit %X Active: yes\n",i); printk(" - Unknown Bit %X Active: yes\n",i);
} }
printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
extp->VccOptimal >> 8, extp->VccOptimal & 0xf); extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
if (extp->VppOptimal) if (extp->VppOptimal)
printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
extp->VppOptimal >> 8, extp->VppOptimal & 0xf); extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
} }
#endif #endif
@ -121,7 +121,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
int i; int i;
if (cfi->cfi_mode) { if (cfi->cfi_mode) {
/* /*
* It's a real CFI chip, not one for which the probe * It's a real CFI chip, not one for which the probe
* routine faked a CFI structure. So we read the feature * routine faked a CFI structure. So we read the feature
* table from it. * table from it.
@ -145,21 +145,21 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
/* Do some byteswapping if necessary */ /* Do some byteswapping if necessary */
extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
#ifdef DEBUG_CFI_FEATURES #ifdef DEBUG_CFI_FEATURES
/* Tell the user about it in lots of lovely detail */ /* Tell the user about it in lots of lovely detail */
cfi_tell_features(extp); cfi_tell_features(extp);
#endif #endif
/* Install our own private info structure */ /* Install our own private info structure */
cfi->cmdset_priv = extp; cfi->cmdset_priv = extp;
} }
for (i=0; i< cfi->numchips; i++) { for (i=0; i< cfi->numchips; i++) {
cfi->chips[i].word_write_time = 128; cfi->chips[i].word_write_time = 128;
cfi->chips[i].buffer_write_time = 128; cfi->chips[i].buffer_write_time = 128;
cfi->chips[i].erase_time = 1024; cfi->chips[i].erase_time = 1024;
} }
return cfi_staa_setup(map); return cfi_staa_setup(map);
} }
@ -187,15 +187,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
mtd->size = devsize * cfi->numchips; mtd->size = devsize * cfi->numchips;
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
* mtd->numeraseregions, GFP_KERNEL); * mtd->numeraseregions, GFP_KERNEL);
if (!mtd->eraseregions) { if (!mtd->eraseregions) {
printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
kfree(cfi->cmdset_priv); kfree(cfi->cmdset_priv);
kfree(mtd); kfree(mtd);
return NULL; return NULL;
} }
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
unsigned long ernum, ersize; unsigned long ernum, ersize;
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@ -228,7 +228,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
mtd->eraseregions[i].numblocks); mtd->eraseregions[i].numblocks);
} }
/* Also select the correct geometry setup too */ /* Also select the correct geometry setup too */
mtd->erase = cfi_staa_erase_varsize; mtd->erase = cfi_staa_erase_varsize;
mtd->read = cfi_staa_read; mtd->read = cfi_staa_read;
mtd->write = cfi_staa_write_buffers; mtd->write = cfi_staa_write_buffers;
@ -259,8 +259,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
adr += chip->start; adr += chip->start;
/* Ensure cmd read/writes are aligned. */ /* Ensure cmd read/writes are aligned. */
cmd_addr = adr & ~(map_bankwidth(map)-1); cmd_addr = adr & ~(map_bankwidth(map)-1);
/* Let's determine this according to the interleave only once */ /* Let's determine this according to the interleave only once */
status_OK = CMD(0x80); status_OK = CMD(0x80);
@ -276,7 +276,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
case FL_ERASING: case FL_ERASING:
if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
goto sleep; /* We don't support erase suspend */ goto sleep; /* We don't support erase suspend */
map_write (map, CMD(0xb0), cmd_addr); map_write (map, CMD(0xb0), cmd_addr);
/* If the flash has finished erasing, then 'erase suspend' /* If the flash has finished erasing, then 'erase suspend'
* appears to make some (28F320) flash devices switch to * appears to make some (28F320) flash devices switch to
@ -291,7 +291,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
status = map_read(map, cmd_addr); status = map_read(map, cmd_addr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
/* Urgh */ /* Urgh */
map_write(map, CMD(0xd0), cmd_addr); map_write(map, CMD(0xd0), cmd_addr);
@ -303,17 +303,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
"suspended: status = 0x%lx\n", status.x[0]); "suspended: status = 0x%lx\n", status.x[0]);
return -EIO; return -EIO;
} }
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
cfi_udelay(1); cfi_udelay(1);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
} }
suspended = 1; suspended = 1;
map_write(map, CMD(0xff), cmd_addr); map_write(map, CMD(0xff), cmd_addr);
chip->state = FL_READY; chip->state = FL_READY;
break; break;
#if 0 #if 0
case FL_WRITING: case FL_WRITING:
/* Not quite yet */ /* Not quite yet */
@ -334,7 +334,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
chip->state = FL_READY; chip->state = FL_READY;
break; break;
} }
/* Urgh. Chip not yet ready to talk to us. */ /* Urgh. Chip not yet ready to talk to us. */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
@ -364,17 +364,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
if (suspended) { if (suspended) {
chip->state = chip->oldstate; chip->state = chip->oldstate;
/* What if one interleaved chip has finished and the /* What if one interleaved chip has finished and the
other hasn't? The old code would leave the finished other hasn't? The old code would leave the finished
one in READY mode. That's bad, and caused -EROFS one in READY mode. That's bad, and caused -EROFS
errors to be returned from do_erase_oneblock because errors to be returned from do_erase_oneblock because
that's the only bit it checked for at the time. that's the only bit it checked for at the time.
As the state machine appears to explicitly allow As the state machine appears to explicitly allow
sending the 0x70 (Read Status) command to an erasing sending the 0x70 (Read Status) command to an erasing
chip and expecting it to be ignored, that's what we chip and expecting it to be ignored, that's what we
do. */ do. */
map_write(map, CMD(0xd0), cmd_addr); map_write(map, CMD(0xd0), cmd_addr);
map_write(map, CMD(0x70), cmd_addr); map_write(map, CMD(0x70), cmd_addr);
} }
wake_up(&chip->wq); wake_up(&chip->wq);
@ -414,14 +414,14 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t
*retlen += thislen; *retlen += thislen;
len -= thislen; len -= thislen;
buf += thislen; buf += thislen;
ofs = 0; ofs = 0;
chipnum++; chipnum++;
} }
return ret; return ret;
} }
static inline int do_write_buffer(struct map_info *map, struct flchip *chip, static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long adr, const u_char *buf, int len) unsigned long adr, const u_char *buf, int len)
{ {
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
@ -429,7 +429,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long cmd_adr, timeo; unsigned long cmd_adr, timeo;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
int wbufsize, z; int wbufsize, z;
/* M58LW064A requires bus alignment for buffer wriets -- saw */ /* M58LW064A requires bus alignment for buffer wriets -- saw */
if (adr & (map_bankwidth(map)-1)) if (adr & (map_bankwidth(map)-1))
return -EINVAL; return -EINVAL;
@ -437,10 +437,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
adr += chip->start; adr += chip->start;
cmd_adr = adr & ~(wbufsize-1); cmd_adr = adr & ~(wbufsize-1);
/* Let's determine this according to the interleave only once */ /* Let's determine this according to the interleave only once */
status_OK = CMD(0x80); status_OK = CMD(0x80);
timeo = jiffies + HZ; timeo = jiffies + HZ;
retry: retry:
@ -448,7 +448,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state);
#endif #endif
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
/* Check that the chip's ready to talk to us. /* Check that the chip's ready to talk to us.
* Later, we can actually think about interrupting it * Later, we can actually think about interrupting it
* if it's in FL_ERASING state. * if it's in FL_ERASING state.
@ -457,7 +457,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
switch (chip->state) { switch (chip->state) {
case FL_READY: case FL_READY:
break; break;
case FL_CFI_QUERY: case FL_CFI_QUERY:
case FL_JEDEC_QUERY: case FL_JEDEC_QUERY:
map_write(map, CMD(0x70), cmd_adr); map_write(map, CMD(0x70), cmd_adr);
@ -522,7 +522,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
/* Write length of data to come */ /* Write length of data to come */
map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr );
/* Write data */ /* Write data */
for (z = 0; z < len; for (z = 0; z < len;
z += map_bankwidth(map), buf += map_bankwidth(map)) { z += map_bankwidth(map), buf += map_bankwidth(map)) {
@ -569,7 +569,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
return -EIO; return -EIO;
} }
/* Latency issues. Drop the lock, wait a while and retry */ /* Latency issues. Drop the lock, wait a while and retry */
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
cfi_udelay(1); cfi_udelay(1);
@ -581,9 +581,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
if (!chip->buffer_write_time) if (!chip->buffer_write_time)
chip->buffer_write_time++; chip->buffer_write_time++;
} }
if (z > 1) if (z > 1)
chip->buffer_write_time++; chip->buffer_write_time++;
/* Done and happy. */ /* Done and happy. */
DISABLE_VPP(map); DISABLE_VPP(map);
chip->state = FL_STATUS; chip->state = FL_STATUS;
@ -607,7 +607,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
return 0; return 0;
} }
static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
size_t len, size_t *retlen, const u_char *buf) size_t len, size_t *retlen, const u_char *buf)
{ {
struct map_info *map = mtd->priv; struct map_info *map = mtd->priv;
@ -629,7 +629,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize);
printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len);
#endif #endif
/* Write buffer is worth it only if more than one word to write... */ /* Write buffer is worth it only if more than one word to write... */
while (len > 0) { while (len > 0) {
/* We must not cross write block boundaries */ /* We must not cross write block boundaries */
@ -638,7 +638,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
if (size > len) if (size > len)
size = len; size = len;
ret = do_write_buffer(map, &cfi->chips[chipnum], ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, buf, size); ofs, buf, size);
if (ret) if (ret)
return ret; return ret;
@ -649,13 +649,13 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
len -= size; len -= size;
if (ofs >> cfi->chipshift) { if (ofs >> cfi->chipshift) {
chipnum ++; chipnum ++;
ofs = 0; ofs = 0;
if (chipnum == cfi->numchips) if (chipnum == cfi->numchips)
return 0; return 0;
} }
} }
return 0; return 0;
} }
@ -765,7 +765,7 @@ retry:
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* Urgh. Chip not yet ready to talk to us. */ /* Urgh. Chip not yet ready to talk to us. */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
@ -798,7 +798,7 @@ retry:
map_write(map, CMD(0x20), adr); map_write(map, CMD(0x20), adr);
map_write(map, CMD(0xD0), adr); map_write(map, CMD(0xD0), adr);
chip->state = FL_ERASING; chip->state = FL_ERASING;
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
msleep(1000); msleep(1000);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
@ -823,7 +823,7 @@ retry:
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* OK Still waiting */ /* OK Still waiting */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
@ -833,13 +833,13 @@ retry:
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
return -EIO; return -EIO;
} }
/* Latency issues. Drop the lock, wait a while and retry */ /* Latency issues. Drop the lock, wait a while and retry */
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
cfi_udelay(1); cfi_udelay(1);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
} }
DISABLE_VPP(map); DISABLE_VPP(map);
ret = 0; ret = 0;
@ -864,7 +864,7 @@ retry:
/* Reset the error bits */ /* Reset the error bits */
map_write(map, CMD(0x50), adr); map_write(map, CMD(0x50), adr);
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
if ((chipstatus & 0x30) == 0x30) { if ((chipstatus & 0x30) == 0x30) {
printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
ret = -EIO; ret = -EIO;
@ -913,17 +913,17 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
i = 0; i = 0;
/* Skip all erase regions which are ended before the start of /* Skip all erase regions which are ended before the start of
the requested erase. Actually, to save on the calculations, the requested erase. Actually, to save on the calculations,
we skip to the first erase region which starts after the we skip to the first erase region which starts after the
start of the requested erase, and then go back one. start of the requested erase, and then go back one.
*/ */
while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
i++; i++;
i--; i--;
/* OK, now i is pointing at the erase region in which this /* OK, now i is pointing at the erase region in which this
erase request starts. Check the start of the requested erase request starts. Check the start of the requested
erase range is aligned with the erase size which is in erase range is aligned with the erase size which is in
effect here. effect here.
@ -946,7 +946,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
the address actually falls the address actually falls
*/ */
i--; i--;
if ((instr->addr + instr->len) & (regions[i].erasesize-1)) if ((instr->addr + instr->len) & (regions[i].erasesize-1))
return -EINVAL; return -EINVAL;
@ -958,7 +958,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
while(len) { while(len) {
ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
if (ret) if (ret)
return ret; return ret;
@ -971,15 +971,15 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
if (adr >> cfi->chipshift) { if (adr >> cfi->chipshift) {
adr = 0; adr = 0;
chipnum++; chipnum++;
if (chipnum >= cfi->numchips) if (chipnum >= cfi->numchips)
break; break;
} }
} }
instr->state = MTD_ERASE_DONE; instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr); mtd_erase_callback(instr);
return 0; return 0;
} }
@ -1005,7 +1005,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
case FL_JEDEC_QUERY: case FL_JEDEC_QUERY:
chip->oldstate = chip->state; chip->oldstate = chip->state;
chip->state = FL_SYNCING; chip->state = FL_SYNCING;
/* No need to wake_up() on this state change - /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything * as the whole point is that nobody can do anything
* with the chip now anyway. * with the chip now anyway.
*/ */
@ -1016,11 +1016,11 @@ static void cfi_staa_sync (struct mtd_info *mtd)
default: default:
/* Not an idle state */ /* Not an idle state */
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
schedule(); schedule();
remove_wait_queue(&chip->wq, &wait); remove_wait_queue(&chip->wq, &wait);
goto retry; goto retry;
} }
} }
@ -1031,7 +1031,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
if (chip->state == FL_SYNCING) { if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate; chip->state = chip->oldstate;
wake_up(&chip->wq); wake_up(&chip->wq);
@ -1066,9 +1066,9 @@ retry:
case FL_STATUS: case FL_STATUS:
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* Urgh. Chip not yet ready to talk to us. */ /* Urgh. Chip not yet ready to talk to us. */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
@ -1097,7 +1097,7 @@ retry:
map_write(map, CMD(0x60), adr); map_write(map, CMD(0x60), adr);
map_write(map, CMD(0x01), adr); map_write(map, CMD(0x01), adr);
chip->state = FL_LOCKING; chip->state = FL_LOCKING;
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
msleep(1000); msleep(1000);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
@ -1111,7 +1111,7 @@ retry:
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* OK Still waiting */ /* OK Still waiting */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
@ -1121,13 +1121,13 @@ retry:
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
return -EIO; return -EIO;
} }
/* Latency issues. Drop the lock, wait a while and retry */ /* Latency issues. Drop the lock, wait a while and retry */
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
cfi_udelay(1); cfi_udelay(1);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
} }
/* Done and happy. */ /* Done and happy. */
chip->state = FL_STATUS; chip->state = FL_STATUS;
DISABLE_VPP(map); DISABLE_VPP(map);
@ -1171,8 +1171,8 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
#endif #endif
if (ret) if (ret)
return ret; return ret;
@ -1182,7 +1182,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
if (adr >> cfi->chipshift) { if (adr >> cfi->chipshift) {
adr = 0; adr = 0;
chipnum++; chipnum++;
if (chipnum >= cfi->numchips) if (chipnum >= cfi->numchips)
break; break;
} }
@ -1217,7 +1217,7 @@ retry:
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* Urgh. Chip not yet ready to talk to us. */ /* Urgh. Chip not yet ready to talk to us. */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
@ -1246,7 +1246,7 @@ retry:
map_write(map, CMD(0x60), adr); map_write(map, CMD(0x60), adr);
map_write(map, CMD(0xD0), adr); map_write(map, CMD(0xD0), adr);
chip->state = FL_UNLOCKING; chip->state = FL_UNLOCKING;
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
msleep(1000); msleep(1000);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
@ -1260,7 +1260,7 @@ retry:
status = map_read(map, adr); status = map_read(map, adr);
if (map_word_andequal(map, status, status_OK, status_OK)) if (map_word_andequal(map, status, status_OK, status_OK))
break; break;
/* OK Still waiting */ /* OK Still waiting */
if (time_after(jiffies, timeo)) { if (time_after(jiffies, timeo)) {
map_write(map, CMD(0x70), adr); map_write(map, CMD(0x70), adr);
@ -1270,13 +1270,13 @@ retry:
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
return -EIO; return -EIO;
} }
/* Latency issues. Drop the unlock, wait a while and retry */ /* Latency issues. Drop the unlock, wait a while and retry */
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
cfi_udelay(1); cfi_udelay(1);
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
} }
/* Done and happy. */ /* Done and happy. */
chip->state = FL_STATUS; chip->state = FL_STATUS;
DISABLE_VPP(map); DISABLE_VPP(map);
@ -1301,7 +1301,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
{ {
unsigned long temp_adr = adr; unsigned long temp_adr = adr;
unsigned long temp_len = len; unsigned long temp_len = len;
cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
while (temp_len) { while (temp_len) {
printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
@ -1319,7 +1319,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
#endif #endif
return ret; return ret;
} }
@ -1343,7 +1343,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
case FL_JEDEC_QUERY: case FL_JEDEC_QUERY:
chip->oldstate = chip->state; chip->oldstate = chip->state;
chip->state = FL_PM_SUSPENDED; chip->state = FL_PM_SUSPENDED;
/* No need to wake_up() on this state change - /* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything * as the whole point is that nobody can do anything
* with the chip now anyway. * with the chip now anyway.
*/ */
@ -1362,9 +1362,9 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
if (ret) { if (ret) {
for (i--; i >=0; i--) { for (i--; i >=0; i--) {
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
if (chip->state == FL_PM_SUSPENDED) { if (chip->state == FL_PM_SUSPENDED) {
/* No need to force it into a known state here, /* No need to force it into a known state here,
because we're returning failure, and it didn't because we're returning failure, and it didn't
@ -1374,8 +1374,8 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
} }
spin_unlock_bh(chip->mutex); spin_unlock_bh(chip->mutex);
} }
} }
return ret; return ret;
} }
@ -1387,11 +1387,11 @@ static void cfi_staa_resume(struct mtd_info *mtd)
struct flchip *chip; struct flchip *chip;
for (i=0; i<cfi->numchips; i++) { for (i=0; i<cfi->numchips; i++) {
chip = &cfi->chips[i]; chip = &cfi->chips[i];
spin_lock_bh(chip->mutex); spin_lock_bh(chip->mutex);
/* Go to known state. Chip may have been power cycled */ /* Go to known state. Chip may have been power cycled */
if (chip->state == FL_PM_SUSPENDED) { if (chip->state == FL_PM_SUSPENDED) {
map_write(map, CMD(0xFF), 0); map_write(map, CMD(0xFF), 0);

View File

@ -1,7 +1,7 @@
/* /*
Common Flash Interface probe code. Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd. (C) 2000 Red Hat. GPL'd.
$Id: cfi_probe.c,v 1.83 2004/11/16 18:19:02 nico Exp $ $Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $
*/ */
#include <linux/config.h> #include <linux/config.h>
@ -20,7 +20,7 @@
#include <linux/mtd/cfi.h> #include <linux/mtd/cfi.h>
#include <linux/mtd/gen_probe.h> #include <linux/mtd/gen_probe.h>
//#define DEBUG_CFI //#define DEBUG_CFI
#ifdef DEBUG_CFI #ifdef DEBUG_CFI
static void print_cfi_ident(struct cfi_ident *); static void print_cfi_ident(struct cfi_ident *);
@ -103,7 +103,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
unsigned long *chip_map, struct cfi_private *cfi) unsigned long *chip_map, struct cfi_private *cfi)
{ {
int i; int i;
if ((base + 0) >= map->size) { if ((base + 0) >= map->size) {
printk(KERN_NOTICE printk(KERN_NOTICE
"Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n", "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n",
@ -128,7 +128,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
} }
if (!cfi->numchips) { if (!cfi->numchips) {
/* This is the first time we're called. Set up the CFI /* This is the first time we're called. Set up the CFI
stuff accordingly and return */ stuff accordingly and return */
return cfi_chip_setup(map, cfi); return cfi_chip_setup(map, cfi);
} }
@ -138,13 +138,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
unsigned long start; unsigned long start;
if(!test_bit(i, chip_map)) { if(!test_bit(i, chip_map)) {
/* Skip location; no valid chip at this address */ /* Skip location; no valid chip at this address */
continue; continue;
} }
start = i << cfi->chipshift; start = i << cfi->chipshift;
/* This chip should be in read mode if it's one /* This chip should be in read mode if it's one
we've already touched. */ we've already touched. */
if (qry_present(map, start, cfi)) { if (qry_present(map, start, cfi)) {
/* Eep. This chip also had the QRY marker. /* Eep. This chip also had the QRY marker.
* Is it an alias for the new one? */ * Is it an alias for the new one? */
cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
@ -156,13 +156,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
map->name, base, start); map->name, base, start);
return 0; return 0;
} }
/* Yes, it's actually got QRY for data. Most /* Yes, it's actually got QRY for data. Most
* unfortunate. Stick the new chip in read mode * unfortunate. Stick the new chip in read mode
* too and if it's the same, assume it's an alias. */ * too and if it's the same, assume it's an alias. */
/* FIXME: Use other modes to do a proper check */ /* FIXME: Use other modes to do a proper check */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
if (qry_present(map, base, cfi)) { if (qry_present(map, base, cfi)) {
xip_allowed(base, map); xip_allowed(base, map);
printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
@ -171,12 +171,12 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
} }
} }
} }
/* OK, if we got to here, then none of the previous chips appear to /* OK, if we got to here, then none of the previous chips appear to
be aliases for the current one. */ be aliases for the current one. */
set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
cfi->numchips++; cfi->numchips++;
/* Put it back into Read Mode */ /* Put it back into Read Mode */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
@ -185,11 +185,11 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
map->name, cfi->interleave, cfi->device_type*8, base, map->name, cfi->interleave, cfi->device_type*8, base,
map->bankwidth*8); map->bankwidth*8);
return 1; return 1;
} }
static int __xipram cfi_chip_setup(struct map_info *map, static int __xipram cfi_chip_setup(struct map_info *map,
struct cfi_private *cfi) struct cfi_private *cfi)
{ {
int ofs_factor = cfi->interleave*cfi->device_type; int ofs_factor = cfi->interleave*cfi->device_type;
@ -209,11 +209,11 @@ static int __xipram cfi_chip_setup(struct map_info *map,
printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
return 0; return 0;
} }
memset(cfi->cfiq,0,sizeof(struct cfi_ident)); memset(cfi->cfiq,0,sizeof(struct cfi_ident));
cfi->cfi_mode = CFI_MODE_CFI; cfi->cfi_mode = CFI_MODE_CFI;
/* Read the CFI info structure */ /* Read the CFI info structure */
xip_disable_qry(base, map, cfi); xip_disable_qry(base, map, cfi);
for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
@ -231,7 +231,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
cfi->mfr = cfi_read_query(map, base); cfi->mfr = cfi_read_query(map, base);
cfi->id = cfi_read_query(map, base + ofs_factor); cfi->id = cfi_read_query(map, base + ofs_factor);
/* Put it back into Read Mode */ /* Put it back into Read Mode */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
@ -255,10 +255,10 @@ static int __xipram cfi_chip_setup(struct map_info *map,
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]); cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);
#ifdef DEBUG_CFI #ifdef DEBUG_CFI
printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n", printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff,
(cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
#endif #endif
} }
@ -271,33 +271,33 @@ static int __xipram cfi_chip_setup(struct map_info *map,
} }
#ifdef DEBUG_CFI #ifdef DEBUG_CFI
static char *vendorname(__u16 vendor) static char *vendorname(__u16 vendor)
{ {
switch (vendor) { switch (vendor) {
case P_ID_NONE: case P_ID_NONE:
return "None"; return "None";
case P_ID_INTEL_EXT: case P_ID_INTEL_EXT:
return "Intel/Sharp Extended"; return "Intel/Sharp Extended";
case P_ID_AMD_STD: case P_ID_AMD_STD:
return "AMD/Fujitsu Standard"; return "AMD/Fujitsu Standard";
case P_ID_INTEL_STD: case P_ID_INTEL_STD:
return "Intel/Sharp Standard"; return "Intel/Sharp Standard";
case P_ID_AMD_EXT: case P_ID_AMD_EXT:
return "AMD/Fujitsu Extended"; return "AMD/Fujitsu Extended";
case P_ID_WINBOND: case P_ID_WINBOND:
return "Winbond Standard"; return "Winbond Standard";
case P_ID_ST_ADV: case P_ID_ST_ADV:
return "ST Advanced"; return "ST Advanced";
case P_ID_MITSUBISHI_STD: case P_ID_MITSUBISHI_STD:
return "Mitsubishi Standard"; return "Mitsubishi Standard";
case P_ID_MITSUBISHI_EXT: case P_ID_MITSUBISHI_EXT:
return "Mitsubishi Extended"; return "Mitsubishi Extended";
@ -306,13 +306,13 @@ static char *vendorname(__u16 vendor)
case P_ID_INTEL_PERFORMANCE: case P_ID_INTEL_PERFORMANCE:
return "Intel Performance Code"; return "Intel Performance Code";
case P_ID_INTEL_DATA: case P_ID_INTEL_DATA:
return "Intel Data"; return "Intel Data";
case P_ID_RESERVED: case P_ID_RESERVED:
return "Not Allowed / Reserved for Future Use"; return "Not Allowed / Reserved for Future Use";
default: default:
return "Unknown"; return "Unknown";
} }
@ -325,21 +325,21 @@ static void print_cfi_ident(struct cfi_ident *cfip)
if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
printk("Invalid CFI ident structure.\n"); printk("Invalid CFI ident structure.\n");
return; return;
} }
#endif #endif
printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID)); printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
if (cfip->P_ADR) if (cfip->P_ADR)
printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR); printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
else else
printk("No Primary Algorithm Table\n"); printk("No Primary Algorithm Table\n");
printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID)); printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));
if (cfip->A_ADR) if (cfip->A_ADR)
printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR); printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);
else else
printk("No Alternate Algorithm Table\n"); printk("No Alternate Algorithm Table\n");
printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
if (cfip->VppMin) { if (cfip->VppMin) {
@ -348,61 +348,61 @@ static void print_cfi_ident(struct cfi_ident *cfip)
} }
else else
printk("No Vpp line\n"); printk("No Vpp line\n");
printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp); printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp)); printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp); printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp)); printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
} }
else else
printk("Full buffer write not supported\n"); printk("Full buffer write not supported\n");
printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp); printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp);
printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp)); printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) { if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp); printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp);
printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp)); printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));
} }
else else
printk("Chip erase not supported\n"); printk("Chip erase not supported\n");
printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20)); printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));
printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc); printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);
switch(cfip->InterfaceDesc) { switch(cfip->InterfaceDesc) {
case 0: case 0:
printk(" - x8-only asynchronous interface\n"); printk(" - x8-only asynchronous interface\n");
break; break;
case 1: case 1:
printk(" - x16-only asynchronous interface\n"); printk(" - x16-only asynchronous interface\n");
break; break;
case 2: case 2:
printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n"); printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n");
break; break;
case 3: case 3:
printk(" - x32-only asynchronous interface\n"); printk(" - x32-only asynchronous interface\n");
break; break;
case 4: case 4:
printk(" - supports x16 and x32 via Word# with asynchronous interface\n"); printk(" - supports x16 and x32 via Word# with asynchronous interface\n");
break; break;
case 65535: case 65535:
printk(" - Not Allowed / Reserved\n"); printk(" - Not Allowed / Reserved\n");
break; break;
default: default:
printk(" - Unknown\n"); printk(" - Unknown\n");
break; break;
} }
printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize); printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);
printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions); printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);
} }
#endif /* DEBUG_CFI */ #endif /* DEBUG_CFI */

View File

@ -7,7 +7,7 @@
* *
* This code is covered by the GPL. * This code is covered by the GPL.
* *
* $Id: cfi_util.c,v 1.9 2005/07/20 21:01:14 tpoynor Exp $ * $Id: cfi_util.c,v 1.10 2005/11/07 11:14:23 gleixner Exp $
* *
*/ */
@ -56,7 +56,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
/* Read in the Extended Query Table */ /* Read in the Extended Query Table */
for (i=0; i<size; i++) { for (i=0; i<size; i++) {
((unsigned char *)extp)[i] = ((unsigned char *)extp)[i] =
cfi_read_query(map, base+((adr+i)*ofs_factor)); cfi_read_query(map, base+((adr+i)*ofs_factor));
} }
@ -113,17 +113,17 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
i = 0; i = 0;
/* Skip all erase regions which are ended before the start of /* Skip all erase regions which are ended before the start of
the requested erase. Actually, to save on the calculations, the requested erase. Actually, to save on the calculations,
we skip to the first erase region which starts after the we skip to the first erase region which starts after the
start of the requested erase, and then go back one. start of the requested erase, and then go back one.
*/ */
while (i < mtd->numeraseregions && ofs >= regions[i].offset) while (i < mtd->numeraseregions && ofs >= regions[i].offset)
i++; i++;
i--; i--;
/* OK, now i is pointing at the erase region in which this /* OK, now i is pointing at the erase region in which this
erase request starts. Check the start of the requested erase request starts. Check the start of the requested
erase range is aligned with the erase size which is in erase range is aligned with the erase size which is in
effect here. effect here.
@ -146,7 +146,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
the address actually falls the address actually falls
*/ */
i--; i--;
if ((ofs + len) & (regions[i].erasesize-1)) if ((ofs + len) & (regions[i].erasesize-1))
return -EINVAL; return -EINVAL;
@ -159,7 +159,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
int size = regions[i].erasesize; int size = regions[i].erasesize;
ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk); ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk);
if (ret) if (ret)
return ret; return ret;
@ -173,7 +173,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
if (adr >> cfi->chipshift) { if (adr >> cfi->chipshift) {
adr = 0; adr = 0;
chipnum++; chipnum++;
if (chipnum >= cfi->numchips) if (chipnum >= cfi->numchips)
break; break;
} }

View File

@ -41,7 +41,7 @@ static struct mtd_chip_driver *get_mtd_chip_driver (const char *name)
list_for_each(pos, &chip_drvs_list) { list_for_each(pos, &chip_drvs_list) {
this = list_entry(pos, typeof(*this), list); this = list_entry(pos, typeof(*this), list);
if (!strcmp(this->name, name)) { if (!strcmp(this->name, name)) {
ret = this; ret = this;
break; break;
@ -73,7 +73,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
ret = drv->probe(map); ret = drv->probe(map);
/* We decrease the use count here. It may have been a /* We decrease the use count here. It may have been a
probe-only module, which is no longer required from this probe-only module, which is no longer required from this
point, having given us a handle on (and increased the use point, having given us a handle on (and increased the use
count of) the actual driver code. count of) the actual driver code.
@ -82,7 +82,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
if (ret) if (ret)
return ret; return ret;
return NULL; return NULL;
} }
/* /*

View File

@ -25,7 +25,7 @@ struct fwh_xxlock_thunk {
* so this code has not been tested with interleaved chips, * so this code has not been tested with interleaved chips,
* and will likely fail in that context. * and will likely fail in that context.
*/ */
static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip, static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
unsigned long adr, int len, void *thunk) unsigned long adr, int len, void *thunk)
{ {
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
@ -44,7 +44,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
* - on 64k boundariesand * - on 64k boundariesand
* - bit 1 set high * - bit 1 set high
* - block lock registers are 4MiB lower - overflow subtract (danger) * - block lock registers are 4MiB lower - overflow subtract (danger)
* *
* The address manipulation is first done on the logical address * The address manipulation is first done on the logical address
* which is 0 at the start of the chip, and then the offset of * which is 0 at the start of the chip, and then the offset of
* the individual chip is addted to it. Any other order a weird * the individual chip is addted to it. Any other order a weird
@ -93,7 +93,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len, ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
(void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK); (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK);
return ret; return ret;
} }

View File

@ -2,7 +2,7 @@
* Routines common to all CFI-type probes. * Routines common to all CFI-type probes.
* (C) 2001-2003 Red Hat, Inc. * (C) 2001-2003 Red Hat, Inc.
* GPL'd * GPL'd
* $Id: gen_probe.c,v 1.23 2005/08/06 04:40:41 nico Exp $ * $Id: gen_probe.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
@ -26,7 +26,7 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
/* First probe the map to see if we have CFI stuff there. */ /* First probe the map to see if we have CFI stuff there. */
cfi = genprobe_ident_chips(map, cp); cfi = genprobe_ident_chips(map, cp);
if (!cfi) if (!cfi)
return NULL; return NULL;
@ -36,12 +36,12 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
mtd = check_cmd_set(map, 1); /* First the primary cmdset */ mtd = check_cmd_set(map, 1); /* First the primary cmdset */
if (!mtd) if (!mtd)
mtd = check_cmd_set(map, 0); /* Then the secondary */ mtd = check_cmd_set(map, 0); /* Then the secondary */
if (mtd) if (mtd)
return mtd; return mtd;
printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n"); printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
kfree(cfi->cfiq); kfree(cfi->cfiq);
kfree(cfi); kfree(cfi);
map->fldrv_priv = NULL; map->fldrv_priv = NULL;
@ -60,14 +60,14 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
memset(&cfi, 0, sizeof(cfi)); memset(&cfi, 0, sizeof(cfi));
/* Call the probetype-specific code with all permutations of /* Call the probetype-specific code with all permutations of
interleave and device type, etc. */ interleave and device type, etc. */
if (!genprobe_new_chip(map, cp, &cfi)) { if (!genprobe_new_chip(map, cp, &cfi)) {
/* The probe didn't like it */ /* The probe didn't like it */
printk(KERN_DEBUG "%s: Found no %s device at location zero\n", printk(KERN_DEBUG "%s: Found no %s device at location zero\n",
cp->name, map->name); cp->name, map->name);
return NULL; return NULL;
} }
#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD #if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD
probe routines won't ever return a broken CFI structure anyway, probe routines won't ever return a broken CFI structure anyway,
@ -92,13 +92,13 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
} else { } else {
BUG(); BUG();
} }
cfi.numchips = 1; cfi.numchips = 1;
/* /*
* Allocate memory for bitmap of valid chips. * Allocate memory for bitmap of valid chips.
* Align bitmap storage size to full byte. * Align bitmap storage size to full byte.
*/ */
max_chips = map->size >> cfi.chipshift; max_chips = map->size >> cfi.chipshift;
mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0); mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
chip_map = kmalloc(mapsize, GFP_KERNEL); chip_map = kmalloc(mapsize, GFP_KERNEL);
@ -122,7 +122,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
} }
/* /*
* Now allocate the space for the structures we need to return to * Now allocate the space for the structures we need to return to
* our caller, and copy the appropriate data into them. * our caller, and copy the appropriate data into them.
*/ */
@ -154,7 +154,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
return retcfi; return retcfi;
} }
static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp, static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
struct cfi_private *cfi) struct cfi_private *cfi)
{ {
@ -189,7 +189,7 @@ extern cfi_cmdset_fn_t cfi_cmdset_0001;
extern cfi_cmdset_fn_t cfi_cmdset_0002; extern cfi_cmdset_fn_t cfi_cmdset_0002;
extern cfi_cmdset_fn_t cfi_cmdset_0020; extern cfi_cmdset_fn_t cfi_cmdset_0020;
static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
int primary) int primary)
{ {
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
@ -199,7 +199,7 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
cfi_cmdset_fn_t *probe_function; cfi_cmdset_fn_t *probe_function;
sprintf(probename, "cfi_cmdset_%4.4X", type); sprintf(probename, "cfi_cmdset_%4.4X", type);
probe_function = inter_module_get_request(probename, probename); probe_function = inter_module_get_request(probename, probename);
if (probe_function) { if (probe_function) {
@ -221,7 +221,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
{ {
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
if (type == P_ID_NONE || type == P_ID_RESERVED) if (type == P_ID_NONE || type == P_ID_RESERVED)
return NULL; return NULL;

View File

@ -1,6 +1,6 @@
/* JEDEC Flash Interface. /* 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. * commonly use in older AMD chips and is obsolete compared with CFI.
* It is called JEDEC because the JEDEC association distributes the ID codes * It is called JEDEC because the JEDEC association distributes the ID codes
* for the chips. * for the chips.
@ -88,9 +88,9 @@ static const struct JEDECTable JEDEC_table[] = {
static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
static void jedec_sync(struct mtd_info *mtd) {}; 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); 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); size_t *retlen, u_char *buf);
static struct mtd_info *jedec_probe(struct map_info *map); static struct mtd_info *jedec_probe(struct map_info *map);
@ -122,7 +122,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private)); memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
priv = (struct jedec_private *)&MTD[1]; priv = (struct jedec_private *)&MTD[1];
my_bank_size = map->size; my_bank_size = map->size;
if (map->size/my_bank_size > MAX_JEDEC_CHIPS) if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
@ -131,13 +131,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
kfree(MTD); kfree(MTD);
return NULL; return NULL;
} }
for (Base = 0; Base < map->size; Base += my_bank_size) for (Base = 0; Base < map->size; Base += my_bank_size)
{ {
// Perhaps zero could designate all tests? // Perhaps zero could designate all tests?
if (map->buswidth == 0) if (map->buswidth == 0)
map->buswidth = 1; map->buswidth = 1;
if (map->buswidth == 1){ if (map->buswidth == 1){
if (jedec_probe8(map,Base,priv) == 0) { if (jedec_probe8(map,Base,priv) == 0) {
printk("did recognize jedec chip\n"); printk("did recognize jedec chip\n");
@ -150,7 +150,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (map->buswidth == 4) if (map->buswidth == 4)
jedec_probe32(map,Base,priv); jedec_probe32(map,Base,priv);
} }
// Get the biggest sector size // Get the biggest sector size
SectorSize = 0; SectorSize = 0;
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
@ -160,7 +160,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (priv->chips[I].sectorsize > SectorSize) if (priv->chips[I].sectorsize > SectorSize)
SectorSize = priv->chips[I].sectorsize; SectorSize = priv->chips[I].sectorsize;
} }
// Quickly ensure that the other sector sizes are factors of the largest // 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++) for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{ {
@ -169,9 +169,9 @@ static struct mtd_info *jedec_probe(struct map_info *map)
printk("mtd: Failed. Device has incompatible mixed sector sizes\n"); printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
kfree(MTD); kfree(MTD);
return NULL; return NULL;
} }
} }
/* Generate a part name that includes the number of different chips and /* Generate a part name that includes the number of different chips and
other configuration information */ other configuration information */
count = 1; count = 1;
@ -181,13 +181,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{ {
const struct JEDECTable *JEDEC; const struct JEDECTable *JEDEC;
if (priv->chips[I+1].jedec == priv->chips[I].jedec) if (priv->chips[I+1].jedec == priv->chips[I].jedec)
{ {
count++; count++;
continue; continue;
} }
// Locate the chip in the jedec table // Locate the chip in the jedec table
JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec); JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
if (JEDEC == 0) if (JEDEC == 0)
@ -196,11 +196,11 @@ static struct mtd_info *jedec_probe(struct map_info *map)
kfree(MTD); kfree(MTD);
return NULL; return NULL;
} }
if (Uniq != 0) if (Uniq != 0)
strcat(Part,","); strcat(Part,",");
Uniq++; Uniq++;
if (count != 1) if (count != 1)
sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name); sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
else else
@ -208,7 +208,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
if (strlen(Part) > sizeof(Part)*2/3) if (strlen(Part) > sizeof(Part)*2/3)
break; break;
count = 1; count = 1;
} }
/* Determine if the chips are organized in a linear fashion, or if there /* 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 are empty banks. Note, the last bank does not count here, only the
@ -233,7 +233,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
{ {
if (priv->bank_fill[I] != my_bank_size) if (priv->bank_fill[I] != my_bank_size)
priv->is_banked = 1; priv->is_banked = 1;
/* This even could be eliminated, but new de-optimized read/write /* This even could be eliminated, but new de-optimized read/write
functions have to be written */ 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]); printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
@ -242,7 +242,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
printk("mtd: Failed. Cannot handle unsymmetric banking\n"); printk("mtd: Failed. Cannot handle unsymmetric banking\n");
kfree(MTD); kfree(MTD);
return NULL; return NULL;
} }
} }
} }
} }
@ -250,7 +250,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
strcat(Part,", banked"); strcat(Part,", banked");
// printk("Part: '%s'\n",Part); // printk("Part: '%s'\n",Part);
memset(MTD,0,sizeof(*MTD)); memset(MTD,0,sizeof(*MTD));
// strlcpy(MTD->name,Part,sizeof(MTD->name)); // strlcpy(MTD->name,Part,sizeof(MTD->name));
MTD->name = map->name; MTD->name = map->name;
@ -291,7 +291,7 @@ static int checkparity(u_char C)
/* Take an array of JEDEC numbers that represent interleved flash chips /* Take an array of JEDEC numbers that represent interleved flash chips
and process them. Check to make sure they are good JEDEC numbers, look 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, static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
unsigned long base,struct jedec_private *priv) unsigned long base,struct jedec_private *priv)
{ {
@ -306,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) if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
return 0; return 0;
} }
// Finally, just make sure all the chip sizes are the same // Finally, just make sure all the chip sizes are the same
JEDEC = jedec_idtoinf(Mfg[0],Id[0]); JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
if (JEDEC == 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]); printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
return 0; return 0;
} }
Size = JEDEC->size; Size = JEDEC->size;
SectorSize = JEDEC->sectorsize; SectorSize = JEDEC->sectorsize;
for (I = 0; I != Count; I++) for (I = 0; I != Count; I++)
@ -331,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"); printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
return 0; return 0;
} }
} }
// Load the Chips // Load the Chips
@ -345,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"); printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
return 0; return 0;
} }
// Add them to the table // Add them to the table
for (J = 0; J != Count; J++) for (J = 0; J != Count; J++)
{ {
unsigned long Bank; unsigned long Bank;
JEDEC = jedec_idtoinf(Mfg[J],Id[J]); JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
priv->chips[I].jedec = (Mfg[J] << 8) | Id[J]; priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
priv->chips[I].size = JEDEC->size; priv->chips[I].size = JEDEC->size;
@ -364,17 +364,17 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
// log2 n :| // log2 n :|
priv->chips[I].addrshift = 0; priv->chips[I].addrshift = 0;
for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++); for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
// Determine how filled this bank is. // Determine how filled this bank is.
Bank = base & (~(my_bank_size-1)); 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) (JEDEC->size << priv->chips[I].addrshift) - Bank)
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++; I++;
} }
priv->size += priv->chips[I-1].size*Count; priv->size += priv->chips[I-1].size*Count;
return priv->chips[I-1].size; return priv->chips[I-1].size;
} }
@ -392,7 +392,7 @@ static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
// Look for flash using an 8 bit bus interface // Look for flash using an 8 bit bus interface
static int jedec_probe8(struct map_info *map,unsigned long base, static int jedec_probe8(struct map_info *map,unsigned long base,
struct jedec_private *priv) struct jedec_private *priv)
{ {
#define flread(x) map_read8(map,base+x) #define flread(x) map_read8(map,base+x)
#define flwrite(v,x) map_write8(map,v,base+x) #define flwrite(v,x) map_write8(map,v,base+x)
@ -410,20 +410,20 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
OldVal = flread(base); OldVal = flread(base);
for (I = 0; OldVal != flread(base) && I < 10000; I++) for (I = 0; OldVal != flread(base) && I < 10000; I++)
OldVal = flread(base); OldVal = flread(base);
// Reset the chip // Reset the chip
flwrite(Reset,0x555); flwrite(Reset,0x555);
// Send the sequence // Send the sequence
flwrite(AutoSel1,0x555); flwrite(AutoSel1,0x555);
flwrite(AutoSel2,0x2AA); flwrite(AutoSel2,0x2AA);
flwrite(AutoSel3,0x555); flwrite(AutoSel3,0x555);
// Get the JEDEC numbers // Get the JEDEC numbers
Mfg[0] = flread(0); Mfg[0] = flread(0);
Id[0] = flread(1); Id[0] = flread(1);
// printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]); // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
Size = handle_jedecs(map,Mfg,Id,1,base,priv); Size = handle_jedecs(map,Mfg,Id,1,base,priv);
// printk("handle_jedecs Size is %x\n",(unsigned int)Size); // printk("handle_jedecs Size is %x\n",(unsigned int)Size);
if (Size == 0) if (Size == 0)
@ -431,13 +431,13 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
flwrite(Reset,0x555); flwrite(Reset,0x555);
return 0; return 0;
} }
// Reset. // Reset.
flwrite(Reset,0x555); flwrite(Reset,0x555);
return 1; return 1;
#undef flread #undef flread
#undef flwrite #undef flwrite
} }
@ -470,17 +470,17 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
OldVal = flread(base); OldVal = flread(base);
for (I = 0; OldVal != flread(base) && I < 10000; I++) for (I = 0; OldVal != flread(base) && I < 10000; I++)
OldVal = flread(base); OldVal = flread(base);
// Reset the chip // Reset the chip
flwrite(Reset,0x555); flwrite(Reset,0x555);
// Send the sequence // Send the sequence
flwrite(AutoSel1,0x555); flwrite(AutoSel1,0x555);
flwrite(AutoSel2,0x2AA); flwrite(AutoSel2,0x2AA);
flwrite(AutoSel3,0x555); flwrite(AutoSel3,0x555);
// Test #1, JEDEC numbers are readable from 0x??00/0x??01 // 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)) flread(1) != flread(0x101))
{ {
flwrite(Reset,0x555); flwrite(Reset,0x555);
@ -494,14 +494,14 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
OldVal = flread(1); OldVal = flread(1);
for (I = 0; I != 4; I++) for (I = 0; I != 4; I++)
Id[I] = (OldVal >> (I*8)); Id[I] = (OldVal >> (I*8));
Size = handle_jedecs(map,Mfg,Id,4,base,priv); Size = handle_jedecs(map,Mfg,Id,4,base,priv);
if (Size == 0) if (Size == 0)
{ {
flwrite(Reset,0x555); flwrite(Reset,0x555);
return 0; return 0;
} }
/* Check if there is address wrap around within a single bank, if this /* 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 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 we call this routine with the JEDEC return still enabled, if two or
@ -519,27 +519,27 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
// Reset. // Reset.
flwrite(0xF0F0F0F0,0x555); flwrite(0xF0F0F0F0,0x555);
return 1; return 1;
#undef flread #undef flread
#undef flwrite #undef flwrite
} }
/* Linear read. */ /* 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) size_t *retlen, u_char *buf)
{ {
struct map_info *map = mtd->priv; struct map_info *map = mtd->priv;
map_copy_from(map, buf, from, len); map_copy_from(map, buf, from, len);
*retlen = len; *retlen = len;
return 0; return 0;
} }
/* Banked read. Take special care to jump past the holes in the bank /* Banked read. Take special care to jump past the holes in the bank
mapping. This version assumes symetry in the holes.. */ 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) size_t *retlen, u_char *buf)
{ {
struct map_info *map = mtd->priv; struct map_info *map = mtd->priv;
@ -555,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) if (priv->bank_fill[0] - offset < len)
get = priv->bank_fill[0] - offset; get = priv->bank_fill[0] - offset;
bank /= priv->bank_fill[0]; bank /= priv->bank_fill[0];
map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
len -= get; len -= get;
*retlen += get; *retlen += get;
from += 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. */ mode. */
static void jedec_flash_failed(unsigned char code) static void jedec_flash_failed(unsigned char code)
{ {
@ -579,17 +579,17 @@ static void jedec_flash_failed(unsigned char code)
printk("mtd: Programming didn't take\n"); 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 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 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 */ where possible */
static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{ {
// Does IO to the currently selected chip // Does IO to the currently selected chip
#define flread(x) map_read8(map,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)) #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
unsigned long Time = 0; unsigned long Time = 0;
unsigned long NoTime = 0; unsigned long NoTime = 0;
unsigned long start = instr->addr, len = instr->len; unsigned long start = instr->addr, len = instr->len;
@ -603,7 +603,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
(len % mtd->erasesize) != 0 || (len % mtd->erasesize) != 0 ||
(len/mtd->erasesize) == 0) (len/mtd->erasesize) == 0)
return -EINVAL; return -EINVAL;
jedec_flash_chip_scan(priv,start,len); jedec_flash_chip_scan(priv,start,len);
// Start the erase sequence on each chip // Start the erase sequence on each chip
@ -611,16 +611,16 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{ {
unsigned long off; unsigned long off;
struct jedec_flash_chip *chip = priv->chips + I; struct jedec_flash_chip *chip = priv->chips + I;
if (chip->length == 0) if (chip->length == 0)
continue; continue;
if (chip->start + chip->length > chip->size) if (chip->start + chip->length > chip->size)
{ {
printk("DIE\n"); printk("DIE\n");
return -EIO; return -EIO;
} }
flwrite(0xF0,chip->start + 0x555); flwrite(0xF0,chip->start + 0x555);
flwrite(0xAA,chip->start + 0x555); flwrite(0xAA,chip->start + 0x555);
flwrite(0x55,chip->start + 0x2AA); flwrite(0x55,chip->start + 0x2AA);
@ -628,8 +628,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
flwrite(0xAA,chip->start + 0x555); flwrite(0xAA,chip->start + 0x555);
flwrite(0x55,chip->start + 0x2AA); flwrite(0x55,chip->start + 0x2AA);
/* Once we start selecting the erase sectors the delay between each /* Once we start selecting the erase sectors the delay between each
command must not exceed 50us or it will immediately start erasing command must not exceed 50us or it will immediately start erasing
and ignore the other sectors */ and ignore the other sectors */
for (off = 0; off < len; off += chip->sectorsize) for (off = 0; off < len; off += chip->sectorsize)
{ {
@ -641,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"); printk("mtd: Ack! We timed out the erase timer!\n");
return -EIO; return -EIO;
} }
} }
} }
/* We could split this into a timer routine and return early, performing /* We could split this into a timer routine and return early, performing
background erasure.. Maybe later if the need warrents */ background erasure.. Maybe later if the need warrents */
/* Poll the flash for erasure completion, specs say this can take as long /* 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). as 480 seconds to do all the sectors (for a 2 meg flash).
Erasure time is dependent on chip age, temp and wear.. */ Erasure time is dependent on chip age, temp and wear.. */
/* This being a generic routine assumes a 32 bit bus. It does read32s /* 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 */ for all bus widths */
Time = 0; Time = 0;
NoTime = 0; NoTime = 0;
@ -664,20 +664,20 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
unsigned todo[4] = {0,0,0,0}; unsigned todo[4] = {0,0,0,0};
unsigned todo_left = 0; unsigned todo_left = 0;
unsigned J; unsigned J;
if (chip->length == 0) if (chip->length == 0)
continue; 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 */ or nothing up to the interleve count */
for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) 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)))) (chip->base & (~((1<<chip->addrshift)-1))))
{ {
todo_left++; todo_left++;
todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1; todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
} }
} }
/* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1], /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
@ -687,7 +687,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{ {
__u32 Last[4]; __u32 Last[4];
unsigned long Count = 0; unsigned long Count = 0;
/* During erase bit 7 is held low and bit 6 toggles, we watch this, /* 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, should it stop toggling or go high then the erase is completed,
or this is not really flash ;> */ or this is not really flash ;> */
@ -718,23 +718,23 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
__u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF; __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
if (todo[J] == 0) if (todo[J] == 0)
continue; continue;
if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2) if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
{ {
// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2); // printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
continue; continue;
} }
if (Byte1 == Byte2) if (Byte1 == Byte2)
{ {
jedec_flash_failed(Byte3); jedec_flash_failed(Byte3);
return -EIO; return -EIO;
} }
todo[J] = 0; todo[J] = 0;
todo_left--; todo_left--;
} }
/* if (NoTime == 0) /* if (NoTime == 0)
Time += HZ/10 - schedule_timeout(HZ/10);*/ Time += HZ/10 - schedule_timeout(HZ/10);*/
NoTime = 0; NoTime = 0;
@ -751,7 +751,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
break; break;
} }
Count++; Count++;
/* // Count time, max of 15s per sector (according to AMD) /* // Count time, max of 15s per sector (according to AMD)
if (Time > 15*len/mtd->erasesize*HZ) if (Time > 15*len/mtd->erasesize*HZ)
{ {
@ -759,38 +759,38 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
return -EIO; return -EIO;
} */ } */
} }
// Skip to the next chip if we used chip erase // Skip to the next chip if we used chip erase
if (chip->length == chip->size) if (chip->length == chip->size)
off = chip->size; off = chip->size;
else else
off += chip->sectorsize; off += chip->sectorsize;
if (off >= chip->length) if (off >= chip->length)
break; break;
NoTime = 1; NoTime = 1;
} }
for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) 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)))) (chip->base & (~((1<<chip->addrshift)-1))))
priv->chips[J].length = 0; priv->chips[J].length = 0;
} }
} }
//printk("done\n"); //printk("done\n");
instr->state = MTD_ERASE_DONE; instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr); mtd_erase_callback(instr);
return 0; return 0;
#undef flread #undef flread
#undef flwrite #undef flwrite
} }
/* This is the simple flash writing function. It writes to every byte, in /* 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 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!*/ array are identical!*/
static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
size_t *retlen, const u_char *buf) size_t *retlen, const u_char *buf)
@ -800,25 +800,25 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
of addrshift (interleave index) and then adds the control register index. */ 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 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)) #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
struct map_info *map = mtd->priv; struct map_info *map = mtd->priv;
struct jedec_private *priv = map->fldrv_priv; struct jedec_private *priv = map->fldrv_priv;
unsigned long base; unsigned long base;
unsigned long off; unsigned long off;
size_t save_len = len; size_t save_len = len;
if (start + len > mtd->size) if (start + len > mtd->size)
return -EIO; return -EIO;
//printk("Here"); //printk("Here");
//printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len); //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
while (len != 0) while (len != 0)
{ {
struct jedec_flash_chip *chip = priv->chips; struct jedec_flash_chip *chip = priv->chips;
unsigned long bank; unsigned long bank;
unsigned long boffset; unsigned long boffset;
// Compute the base of the flash. // Compute the base of the flash.
off = ((unsigned long)start) % (chip->size << chip->addrshift); off = ((unsigned long)start) % (chip->size << chip->addrshift);
base = start - off; base = start - off;
@ -828,10 +828,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
boffset = base & (priv->bank_fill[0]-1); boffset = base & (priv->bank_fill[0]-1);
bank = (bank/priv->bank_fill[0])*my_bank_size; bank = (bank/priv->bank_fill[0])*my_bank_size;
base = bank + boffset; base = bank + boffset;
// printk("Flasing %X %X %X\n",base,chip->size,len); // printk("Flasing %X %X %X\n",base,chip->size,len);
// printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift); // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
// Loop over this page // Loop over this page
for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++) for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
{ {
@ -845,7 +845,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
} }
if (((~oldbyte) & *buf) != 0) if (((~oldbyte) & *buf) != 0)
printk("mtd: warn: Trying to set a 0 to a 1\n"); printk("mtd: warn: Trying to set a 0 to a 1\n");
// Write // Write
flwrite(0xAA,0x555); flwrite(0xAA,0x555);
flwrite(0x55,0x2AA); flwrite(0x55,0x2AA);
@ -854,10 +854,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
Last[0] = map_read8(map,base + off); Last[0] = map_read8(map,base + off);
Last[1] = map_read8(map,base + off); Last[1] = map_read8(map,base + off);
Last[2] = 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 /* Wait for the flash to finish the operation. We store the last 4
status bytes that have been retrieved so we can determine why 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 */ failure */
for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
Count < 10000; Count++) Count < 10000; Count++)
@ -866,7 +866,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
{ {
jedec_flash_failed(Last[(Count - 3) % 4]); jedec_flash_failed(Last[(Count - 3) % 4]);
return -EIO; return -EIO;
} }
} }
} }
*retlen = save_len; *retlen = save_len;
@ -885,24 +885,24 @@ static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start
// Zero the records // Zero the records
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
priv->chips[I].start = priv->chips[I].length = 0; priv->chips[I].start = priv->chips[I].length = 0;
// Intersect the region with each chip // Intersect the region with each chip
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
{ {
struct jedec_flash_chip *chip = priv->chips + I; struct jedec_flash_chip *chip = priv->chips + I;
unsigned long ByteStart; unsigned long ByteStart;
unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift); unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
// End is before this chip or the start is after it // End is before this chip or the start is after it
if (start+len < chip->offset || if (start+len < chip->offset ||
ChipEndByte - (1 << chip->addrshift) < start) ChipEndByte - (1 << chip->addrshift) < start)
continue; continue;
if (start < chip->offset) if (start < chip->offset)
{ {
ByteStart = chip->offset; ByteStart = chip->offset;
chip->start = 0; chip->start = 0;
} }
else else
{ {
chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift; chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;

View File

@ -1,7 +1,7 @@
/* /*
Common Flash Interface probe code. Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd. (C) 2000 Red Hat. GPL'd.
$Id: jedec_probe.c,v 1.63 2005/02/14 16:30:32 bjd Exp $ $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $
See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
for the standard this probe goes back to. for the standard this probe goes back to.
@ -1719,7 +1719,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
static struct mtd_info *jedec_probe(struct map_info *map); static struct mtd_info *jedec_probe(struct map_info *map);
static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
struct cfi_private *cfi) struct cfi_private *cfi)
{ {
map_word result; map_word result;
@ -1730,7 +1730,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
return result.x[0] & mask; return result.x[0] & mask;
} }
static inline u32 jedec_read_id(struct map_info *map, __u32 base, static inline u32 jedec_read_id(struct map_info *map, __u32 base,
struct cfi_private *cfi) struct cfi_private *cfi)
{ {
map_word result; map_word result;
@ -1741,7 +1741,7 @@ static inline u32 jedec_read_id(struct map_info *map, __u32 base,
return result.x[0] & mask; return result.x[0] & mask;
} }
static inline void jedec_reset(u32 base, struct map_info *map, static inline void jedec_reset(u32 base, struct map_info *map,
struct cfi_private *cfi) struct cfi_private *cfi)
{ {
/* Reset */ /* Reset */
@ -1765,7 +1765,7 @@ static inline void jedec_reset(u32 base, struct map_info *map,
* so ensure we're in read mode. Send both the Intel and the AMD command * so ensure we're in read mode. Send both the Intel and the AMD command
* for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
* this should be safe. * this should be safe.
*/ */
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
/* FIXME - should have reset delay before continuing */ /* FIXME - should have reset delay before continuing */
} }
@ -1807,14 +1807,14 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
printk("Found: %s\n",jedec_table[index].name); printk("Found: %s\n",jedec_table[index].name);
num_erase_regions = jedec_table[index].NumEraseRegions; num_erase_regions = jedec_table[index].NumEraseRegions;
p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
if (!p_cfi->cfiq) { if (!p_cfi->cfiq) {
//xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
return 0; return 0;
} }
memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
p_cfi->cfiq->P_ID = jedec_table[index].CmdSet; p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions; p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
@ -1969,7 +1969,7 @@ static inline int jedec_match( __u32 base,
cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
/* FIXME - should have a delay before continuing */ /* FIXME - should have a delay before continuing */
match_done: match_done:
return rc; return rc;
} }
@ -1998,23 +1998,23 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
"Probe at base(0x%08x) past the end of the map(0x%08lx)\n", "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
base, map->size -1); base, map->size -1);
return 0; return 0;
} }
/* Ensure the unlock addresses we try stay inside the map */ /* Ensure the unlock addresses we try stay inside the map */
probe_offset1 = cfi_build_cmd_addr( probe_offset1 = cfi_build_cmd_addr(
cfi->addr_unlock1, cfi->addr_unlock1,
cfi_interleave(cfi), cfi_interleave(cfi),
cfi->device_type); cfi->device_type);
probe_offset2 = cfi_build_cmd_addr( probe_offset2 = cfi_build_cmd_addr(
cfi->addr_unlock1, cfi->addr_unlock1,
cfi_interleave(cfi), cfi_interleave(cfi),
cfi->device_type); cfi->device_type);
if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
((base + probe_offset2 + map_bankwidth(map)) >= map->size)) ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
{ {
goto retry; goto retry;
} }
/* Reset */ /* Reset */
jedec_reset(base, map, cfi); jedec_reset(base, map, cfi);
@ -2027,13 +2027,13 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
/* FIXME - should have a delay before continuing */ /* FIXME - should have a delay before continuing */
if (!cfi->numchips) { if (!cfi->numchips) {
/* This is the first time we're called. Set up the CFI /* This is the first time we're called. Set up the CFI
stuff accordingly and return */ stuff accordingly and return */
cfi->mfr = jedec_read_mfr(map, base, cfi); cfi->mfr = jedec_read_mfr(map, base, cfi);
cfi->id = jedec_read_id(map, base, cfi); cfi->id = jedec_read_id(map, base, cfi);
DEBUG(MTD_DEBUG_LEVEL3, DEBUG(MTD_DEBUG_LEVEL3,
"Search for id:(%02x %02x) interleave(%d) type(%d)\n", "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
@ -2062,7 +2062,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
return 0; return 0;
} }
} }
/* Check each previous chip locations to see if it's an alias */ /* Check each previous chip locations to see if it's an alias */
for (i=0; i < (base >> cfi->chipshift); i++) { for (i=0; i < (base >> cfi->chipshift); i++) {
unsigned long start; unsigned long start;
@ -2083,7 +2083,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
map->name, base, start); map->name, base, start);
return 0; return 0;
} }
/* Yes, it's actually got the device IDs as data. Most /* Yes, it's actually got the device IDs as data. Most
* unfortunate. Stick the new chip in read mode * unfortunate. Stick the new chip in read mode
* too and if it's the same, assume it's an alias. */ * too and if it's the same, assume it's an alias. */
@ -2097,20 +2097,20 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
} }
} }
} }
/* OK, if we got to here, then none of the previous chips appear to /* OK, if we got to here, then none of the previous chips appear to
be aliases for the current one. */ be aliases for the current one. */
set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
cfi->numchips++; cfi->numchips++;
ok_out: ok_out:
/* Put it back into Read Mode */ /* Put it back into Read Mode */
jedec_reset(base, map, cfi); jedec_reset(base, map, cfi);
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
map->name, cfi_interleave(cfi), cfi->device_type*8, base, map->name, cfi_interleave(cfi), cfi->device_type*8, base,
map->bankwidth*8); map->bankwidth*8);
return 1; return 1;
} }

View File

@ -1,11 +1,11 @@
/* /*
* Common code to handle absent "placeholder" devices * Common code to handle absent "placeholder" devices
* Copyright 2001 Resilience Corporation <ebrower@resilience.com> * Copyright 2001 Resilience Corporation <ebrower@resilience.com>
* $Id: map_absent.c,v 1.5 2004/11/16 18:29:00 dwmw2 Exp $ * $Id: map_absent.c,v 1.6 2005/11/07 11:14:23 gleixner Exp $
* *
* This map driver is used to allocate "placeholder" MTD * This map driver is used to allocate "placeholder" MTD
* devices on systems that have socketed/removable media. * devices on systems that have socketed/removable media.
* Use of this driver as a fallback preserves the expected * Use of this driver as a fallback preserves the expected
* registration of MTD device nodes regardless of probe outcome. * registration of MTD device nodes regardless of probe outcome.
* A usage example is as follows: * A usage example is as follows:
* *
@ -80,7 +80,7 @@ static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t
static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
{ {
*retlen = 0; *retlen = 0;
return -ENODEV; return -ENODEV;
} }
static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr) static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr)

View File

@ -4,7 +4,7 @@
* Copyright 2000,2001 David A. Schleef <ds@schleef.org> * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
* 2000,2001 Lineo, Inc. * 2000,2001 Lineo, Inc.
* *
* $Id: sharp.c,v 1.15 2005/08/02 20:36:05 tpoynor Exp $ * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $
* *
* Devices supported: * Devices supported:
* LH28F016SCT Symmetrical block flash memory, 2Mx8 * LH28F016SCT Symmetrical block flash memory, 2Mx8
@ -459,12 +459,12 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
remove_wait_queue(&chip->wq, &wait); remove_wait_queue(&chip->wq, &wait);
//spin_lock_bh(chip->mutex); //spin_lock_bh(chip->mutex);
if (signal_pending(current)){ if (signal_pending(current)){
ret = -EINTR; ret = -EINTR;
goto out; goto out;
} }
} }
ret = -ETIME; ret = -ETIME;
out: out:
@ -563,7 +563,7 @@ static int sharp_suspend(struct mtd_info *mtd)
static void sharp_resume(struct mtd_info *mtd) static void sharp_resume(struct mtd_info *mtd)
{ {
printk("sharp_resume()\n"); printk("sharp_resume()\n");
} }
static void sharp_destroy(struct mtd_info *mtd) static void sharp_destroy(struct mtd_info *mtd)