summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/chips
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/chips')
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c38
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c2
-rw-r--r--drivers/mtd/chips/jedec_probe.c37
3 files changed, 61 insertions, 16 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 2f19fa78d24a..3aa3dca56ae6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -526,7 +526,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
struct cfi_pri_intelext *extp = cfi->cmdset_priv;
/*
- * Probing of multi-partition flash ships.
+ * Probing of multi-partition flash chips.
*
* To support multiple partitions when available, we simply arrange
* for each of them to have their own flchip structure even if they
@@ -653,7 +653,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
resettime:
timeo = jiffies + HZ;
retry:
- if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE)) {
+ if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
/*
* OK. We have possibility for contension on the write/erase
* operations which are global to the real chip and not per
@@ -798,6 +798,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
if (mode == FL_READY && chip->oldstate == FL_READY)
return 0;
+ case FL_SHUTDOWN:
+ /* The machine is rebooting now,so no one can get chip anymore */
+ return -EIO;
default:
sleep:
set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1166,28 +1169,34 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
- unsigned long ofs;
+ unsigned long ofs, last_end = 0;
int chipnum;
int ret = 0;
if (!map->virt || (from + len > mtd->size))
return -EINVAL;
- *mtdbuf = (void *)map->virt + from;
- *retlen = 0;
-
/* Now lock the chip(s) to POINT state */
/* ofs: offset within the first chip that the first read should start */
chipnum = (from >> cfi->chipshift);
ofs = from - (chipnum << cfi->chipshift);
+ *mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs;
+ *retlen = 0;
+
while (len) {
unsigned long thislen;
if (chipnum >= cfi->numchips)
break;
+ /* We cannot point across chips that are virtually disjoint */
+ if (!last_end)
+ last_end = cfi->chips[chipnum].start;
+ else if (cfi->chips[chipnum].start != last_end)
+ break;
+
if ((len + ofs -1) >> cfi->chipshift)
thislen = (1<<cfi->chipshift) - ofs;
else
@@ -1201,6 +1210,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
len -= thislen;
ofs = 0;
+ last_end += 1 << cfi->chipshift;
chipnum++;
}
return 0;
@@ -1780,7 +1790,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
return ret;
}
-int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
+static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
{
unsigned long ofs, len;
int ret;
@@ -1930,7 +1940,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
__FUNCTION__, ofs, len);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
- ofs, len, 0);
+ ofs, len, NULL);
#endif
ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
@@ -1940,7 +1950,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
__FUNCTION__, ret);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
- ofs, len, 0);
+ ofs, len, NULL);
#endif
return ret;
@@ -1954,7 +1964,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
__FUNCTION__, ofs, len);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
- ofs, len, 0);
+ ofs, len, NULL);
#endif
ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
@@ -1964,7 +1974,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
__FUNCTION__, ret);
cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
- ofs, len, 0);
+ ofs, len, NULL);
#endif
return ret;
@@ -2255,7 +2265,7 @@ static void cfi_intelext_save_locks(struct mtd_info *mtd)
adr = region->offset + block * len;
status = cfi_varsize_frob(mtd,
- do_getlockstatus_oneblock, adr, len, 0);
+ do_getlockstatus_oneblock, adr, len, NULL);
if (status)
set_bit(block, region->lockmap);
else
@@ -2402,10 +2412,10 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
and switch to array mode so any bootloader in
flash is accessible for soft reboot. */
spin_lock(chip->mutex);
- ret = get_chip(map, chip, chip->start, FL_SYNCING);
+ ret = get_chip(map, chip, chip->start, FL_SHUTDOWN);
if (!ret) {
map_write(map, CMD(0xff), chip->start);
- chip->state = FL_READY;
+ chip->state = FL_SHUTDOWN;
}
spin_unlock(chip->mutex);
}
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 1f6445840461..389acc600f5e 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1609,7 +1609,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
}
-int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
+static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
{
unsigned long ofs, len;
int ret;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 58e561e87699..a67b23b87fc0 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -70,6 +69,7 @@
/* Fujitsu */
#define MBM29F040C 0x00A4
+#define MBM29F800BA 0x2258
#define MBM29LV650UE 0x22D7
#define MBM29LV320TE 0x22F6
#define MBM29LV320BE 0x22F9
@@ -129,6 +129,7 @@
#define LH28F640BF 0x00b0
/* ST - www.st.com */
+#define M29F800AB 0x0058
#define M29W800DT 0x00D7
#define M29W800DB 0x005B
#define M29W160DT 0x22C4
@@ -646,6 +647,23 @@ static const struct amd_flash_info jedec_table[] = {
}
}, {
.mfr_id = MANUFACTURER_FUJITSU,
+ .dev_id = MBM29F800BA,
+ .name = "Fujitsu MBM29F800BA",
+ .uaddr = {
+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
+ },
+ .DevSize = SIZE_1MiB,
+ .CmdSet = P_ID_AMD_STD,
+ .NumEraseRegions= 4,
+ .regions = {
+ ERASEINFO(0x04000,1),
+ ERASEINFO(0x02000,2),
+ ERASEINFO(0x08000,1),
+ ERASEINFO(0x10000,15),
+ }
+ }, {
+ .mfr_id = MANUFACTURER_FUJITSU,
.dev_id = MBM29LV650UE,
.name = "Fujitsu MBM29LV650UE",
.uaddr = {
@@ -1510,6 +1528,23 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x1000,256)
}
+ }, {
+ .mfr_id = MANUFACTURER_ST,
+ .dev_id = M29F800AB,
+ .name = "ST M29F800AB",
+ .uaddr = {
+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
+ },
+ .DevSize = SIZE_1MiB,
+ .CmdSet = P_ID_AMD_STD,
+ .NumEraseRegions= 4,
+ .regions = {
+ ERASEINFO(0x04000,1),
+ ERASEINFO(0x02000,2),
+ ERASEINFO(0x08000,1),
+ ERASEINFO(0x10000,15),
+ }
}, {
.mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
.dev_id = M29W800DT,