Commit 67d4878e authored by David Woodhouse's avatar David Woodhouse

NOR flash drivers update

 - Handle cached access to flash chips on supporting platforms
 - Handle arrangements of chips larger than a single bus width
 - Clean up the AMD/Fujitsu chip driver
 - Update board 'mapping' drivers to match
 - New mapping drivers for new platforms.
parent 7df80b4c
# $Id: Kconfig,v 1.3 2003/05/28 11:02:23 dwmw2 Exp $
# $Id: Kconfig,v 1.5 2004/06/04 15:59:32 gleixner Exp $
menu "Memory Technology Devices (MTD)"
......@@ -68,9 +68,23 @@ config MTD_REDBOOT_PARTS
SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
example.
config MTD_REDBOOT_PARTS_UNALLOCATED
bool " Include unallocated flash regions"
depends on MTD_REDBOOT_PARTS
help
If you need to register each unallocated flash region as a MTD
'partition', enable this option.
config MTD_REDBOOT_PARTS_READONLY
bool " Force read-only for RedBoot system images"
depends on MTD_REDBOOT_PARTS
help
If you need to force read-only for 'RedBoot', 'RedBoot Config' and
'FIS directory' images, enable this option.
config MTD_CMDLINE_PARTS
tristate "Command line partition table parsing"
depends on MTD_PARTITIONS
bool "Command line partition table parsing"
depends on MTD_PARTITIONS = "y"
---help---
Allow generic configuration of the MTD paritition tables via the kernel
command line. Multiple flash resources are supported for hardware where
......
#
# Makefile for the memory technology device drivers.
#
# $Id: Makefile.common,v 1.2 2003/05/23 11:38:29 dwmw2 Exp $
# *** BIG UGLY NOTE ***
#
# The shiny new inter_module_xxx has introduced yet another ugly link
# order dependency, which I'd previously taken great care to avoid.
# We now have to ensure that the chip drivers are initialised before the
# map drivers, and that the doc200[01] drivers are initialised before
# docprobe.
#
# We'll hopefully merge the doc200[01] drivers and docprobe back into
# a single driver some time soon, but the CFI drivers are going to have
# to stay like that.
#
# Urgh.
#
# dwmw2 21/11/0
# $Id: Makefile.common,v 1.3 2004/07/12 16:07:30 dwmw2 Exp $
# Core functionality.
obj-$(CONFIG_MTD) += mtdcore.o
......
# drivers/mtd/chips/Kconfig
# $Id: Kconfig,v 1.3 2003/05/28 15:13:24 dwmw2 Exp $
# $Id: Kconfig,v 1.8 2004/07/13 22:32:02 dwmw2 Exp $
menu "RAM/ROM/Flash chip drivers"
depends on MTD!=n
......@@ -85,59 +85,72 @@ config MTD_CFI_GEOMETRY
arrangements of CFI chips. If unsure, say 'N' and all options
which are supported by the current code will be enabled.
config MTD_CFI_B1
bool "Support 8-bit buswidth"
depends on MTD_CFI_GEOMETRY
config MTD_MAP_BANK_WIDTH_1
bool "Support 8-bit buswidth" if MTD_CFI_GEOMETRY
default y
help
If you wish to support CFI devices on a physical bus which is
8 bits wide, say 'Y'.
config MTD_CFI_B2
bool "Support 16-bit buswidth"
depends on MTD_CFI_GEOMETRY
config MTD_MAP_BANK_WIDTH_2
bool "Support 16-bit buswidth" if MTD_CFI_GEOMETRY
default y
help
If you wish to support CFI devices on a physical bus which is
16 bits wide, say 'Y'.
config MTD_CFI_B4
bool "Support 32-bit buswidth"
depends on MTD_CFI_GEOMETRY
config MTD_MAP_BANK_WIDTH_4
bool "Support 32-bit buswidth" if MTD_CFI_GEOMETRY
default y
help
If you wish to support CFI devices on a physical bus which is
32 bits wide, say 'Y'.
config MTD_CFI_B8
bool "Support 64-bit buswidth"
depends on MTD_CFI_GEOMETRY
config MTD_MAP_BANK_WIDTH_8
bool "Support 64-bit buswidth" if MTD_CFI_GEOMETRY
default n
help
If you wish to support CFI devices on a physical bus which is
64 bits wide, say 'Y'.
config MTD_MAP_BANK_WIDTH_16
bool "Support 128-bit buswidth" if MTD_CFI_GEOMETRY
default n
help
If you wish to support CFI devices on a physical bus which is
128 bits wide, say 'Y'.
config MTD_MAP_BANK_WIDTH_32
bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY
default n
help
If you wish to support CFI devices on a physical bus which is
256 bits wide, say 'Y'.
config MTD_CFI_I1
bool "Support 1-chip flash interleave" if !MTD_CFI_B1
depends on MTD_CFI_GEOMETRY
default y if MTD_CFI_B1
bool "Support 1-chip flash interleave" if MTD_CFI_GEOMETRY
default y
help
If your flash chips are not interleaved - i.e. you only have one
flash chip addressed by each bus cycle, then say 'Y'.
config MTD_CFI_I2
bool "Support 2-chip flash interleave"
depends on MTD_CFI_GEOMETRY
bool "Support 2-chip flash interleave" if MTD_CFI_GEOMETRY
default y
help
If your flash chips are interleaved in pairs - i.e. you have two
flash chips addressed by each bus cycle, then say 'Y'.
config MTD_CFI_I4
bool "Support 4-chip flash interleave"
depends on MTD_CFI_GEOMETRY
bool "Support 4-chip flash interleave" if MTD_CFI_GEOMETRY
default n
help
If your flash chips are interleaved in fours - i.e. you have four
flash chips addressed by each bus cycle, then say 'Y'.
config MTD_CFI_I8
bool "Support 8-chip flash interleave"
depends on MTD_CFI_GEOMETRY
bool "Support 8-chip flash interleave" if MTD_CFI_GEOMETRY
default n
help
If your flash chips are interleaved in eights - i.e. you have eight
flash chips addressed by each bus cycle, then say 'Y'.
......@@ -160,6 +173,27 @@ config MTD_CFI_AMDSTD
provides support for one of those command sets, used on chips
including the AMD Am29LV320.
config MTD_CFI_AMDSTD_RETRY
int "Retry failed commands (erase/program)"
depends on MTD_CFI_AMDSTD
default "0"
help
Some chips, when attached to a shared bus, don't properly filter
bus traffic that is destined to other devices. This broken
behavior causes erase and program sequences to be aborted when
the sequences are mixed with traffic for other devices.
SST49LF040 (and related) chips are know to be broken.
config MTD_CFI_AMDSTD_RETRY_MAX
int "Max retries of failed commands (erase/program)"
depends on MTD_CFI_AMDSTD_RETRY
default "0"
help
If you have an SST49LF040 (or related chip) then this value should
be set to at least 1. This can also be adjusted at driver load
time with the retry_cmd_max module parameter.
config MTD_CFI_STAA
tristate "Support for ST (Advanced Architecture) flash chips"
depends on MTD_GEN_PROBE
......@@ -168,6 +202,11 @@ config MTD_CFI_STAA
sets which a CFI-compliant chip may claim to implement. This code
provides support for one of those command sets.
config MTD_CFI_UTIL
tristate
default y if MTD_CFI_INTELEXT=y || MTD_CFI_AMDSTD=y || MTD_CFI_STAA=y
default m if MTD_CFI_INTELEXT=m || MTD_CFI_AMDSTD=m || MTD_CFI_STAA=m
config MTD_RAM
tristate "Support for RAM chips in bus mapping"
depends on MTD
......
#
# linux/drivers/chips/Makefile
#
# $Id: Makefile.common,v 1.1 2003/05/21 15:00:01 dwmw2 Exp $
# $Id: Makefile.common,v 1.4 2004/07/12 16:07:30 dwmw2 Exp $
# *** BIG UGLY NOTE ***
#
# The removal of get_module_symbol() and replacement with
# inter_module_register() et al has introduced a link order dependency
# here where previously there was none. We now have to ensure that
# the CFI command set drivers are linked before cfi_probe.o
# the CFI command set drivers are linked before gen_probe.o
obj-$(CONFIG_MTD) += chipreg.o
obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
obj-$(CONFIG_MTD_CFI) += cfi_probe.o
obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o
obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
......
......@@ -3,7 +3,7 @@
*
* Author: Jonas Holmberg <jonas.holmberg@axis.com>
*
* $Id: amd_flash.c,v 1.23 2003/06/12 09:24:13 dwmw2 Exp $
* $Id: amd_flash.c,v 1.24 2004/07/12 13:34:30 dwmw2 Exp $
*
* Copyright (c) 2001 Axis Communications AB
*
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
Common Flash Interface probe code.
(C) 2000 Red Hat. GPL'd.
$Id: cfi_probe.c,v 1.71 2003/05/28 12:51:48 dwmw2 Exp $
$Id: cfi_probe.c,v 1.77 2004/07/14 08:38:44 dwmw2 Exp $
*/
#include <linux/config.h>
......@@ -26,7 +26,7 @@ static void print_cfi_ident(struct cfi_ident *);
#endif
static int cfi_probe_chip(struct map_info *map, __u32 base,
struct flchip *chips, struct cfi_private *cfi);
unsigned long *chip_map, struct cfi_private *cfi);
static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi);
struct mtd_info *cfi_probe(struct map_info *map);
......@@ -35,21 +35,36 @@ struct mtd_info *cfi_probe(struct map_info *map);
in: interleave,type,mode
ret: table index, <0 for error
*/
static inline int qry_present(struct map_info *map, __u32 base,
static int qry_present(struct map_info *map, __u32 base,
struct cfi_private *cfi)
{
int osf = cfi->interleave * cfi->device_type; // scale factor
map_word val;
map_word qry;
if (cfi_read(map,base+osf*0x10)==cfi_build_cmd('Q',map,cfi) &&
cfi_read(map,base+osf*0x11)==cfi_build_cmd('R',map,cfi) &&
cfi_read(map,base+osf*0x12)==cfi_build_cmd('Y',map,cfi))
return 1; // ok !
qry = cfi_build_cmd('Q', map, cfi);
val = map_read(map, base + osf*0x10);
return 0; // nothing found
if (!map_word_equal(map, qry, val))
return 0;
qry = cfi_build_cmd('R', map, cfi);
val = map_read(map, base + osf*0x11);
if (!map_word_equal(map, qry, val))
return 0;
qry = cfi_build_cmd('Y', map, cfi);
val = map_read(map, base + osf*0x12);
if (!map_word_equal(map, qry, val))
return 0;
return 1; // nothing found
}
static int cfi_probe_chip(struct map_info *map, __u32 base,
struct flchip *chips, struct cfi_private *cfi)
unsigned long *chip_map, struct cfi_private *cfi)
{
int i;
......@@ -66,6 +81,7 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
return 0;
}
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(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
if (!qry_present(map,base,cfi))
......@@ -78,18 +94,25 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
}
/* Check each previous chip to see if it's an alias */
for (i=0; i<cfi->numchips; i++) {
for (i=0; i < (base >> cfi->chipshift); i++) {
unsigned long start;
if(!test_bit(i, chip_map)) {
/* Skip location; no valid chip at this address */
continue;
}
start = i << cfi->chipshift;
/* This chip should be in read mode if it's one
we've already touched. */
if (qry_present(map,chips[i].start,cfi)) {
if (qry_present(map, start, cfi)) {
/* Eep. This chip also had the QRY marker.
* Is it an alias for the new one? */
cfi_send_gen_cmd(0xF0, 0, chips[i].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);
/* If the QRY marker goes away, it's an alias */
if (!qry_present(map, chips[i].start, cfi)) {
if (!qry_present(map, start, cfi)) {
printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
map->name, base, chips[i].start);
map->name, base, start);
return 0;
}
/* Yes, it's actually got QRY for data. Most
......@@ -97,10 +120,11 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
* too and if it's the same, assume it's an alias. */
/* 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(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
if (qry_present(map, base, cfi)) {
printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
map->name, base, chips[i].start);
map->name, base, start);
return 0;
}
}
......@@ -108,21 +132,16 @@ static int cfi_probe_chip(struct map_info *map, __u32 base,
/* OK, if we got to here, then none of the previous chips appear to
be aliases for the current one. */
if (cfi->numchips == MAX_CFI_CHIPS) {
printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
/* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
return -1;
}
chips[cfi->numchips].start = base;
chips[cfi->numchips].state = FL_READY;
set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
cfi->numchips++;
/* Put it back into Read Mode */
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);
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\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->buswidth*8);
map->bankwidth*8);
return 1;
}
......@@ -150,7 +169,6 @@ static int cfi_chip_setup(struct map_info *map,
memset(cfi->cfiq,0,sizeof(struct cfi_ident));
cfi->cfi_mode = CFI_MODE_CFI;
cfi->fast_prog=1; /* CFI supports fast programming */
/* Read the CFI info structure */
for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) {
......@@ -180,8 +198,29 @@ static int cfi_chip_setup(struct map_info *map,
(cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
#endif
}
/* Note we put the device back into Read Mode BEFORE going into Auto
* Select Mode, as some devices support nesting of modes, others
* don't. This way should always work.
* On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
* so should be treated as nops or illegal (and so put the device
* back into Read Mode, which is a nop in this case).
*/
cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xaa, 0x555, 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->mfr = cfi_read_query(map, base);
cfi->id = cfi_read_query(map, base + ofs_factor);
/* Put it back into Read Mode */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
/* ... even if it's an Intel chip */
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
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->bankwidth*8);
return 1;
}
......@@ -241,11 +280,11 @@ static void print_cfi_ident(struct cfi_ident *cfip)
printk("No Alternate Algorithm Table\n");
printk("Vcc Minimum: %x.%x V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
printk("Vcc Maximum: %x.%x V\n", cfip->VccMax >> 4, cfip->VccMax & 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);
if (cfip->VppMin) {
printk("Vpp Minimum: %x.%x V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
printk("Vpp Maximum: %x.%x V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
printk("Vpp Minimum: %2d.%d V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
printk("Vpp Maximum: %2d.%d V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
}
else
printk("No Vpp line\n");
......
/*
* Common Flash Interface support:
* Generic utility functions not dependant on command set
*
* Copyright (C) 2002 Red Hat
* Copyright (C) 2003 STMicroelectronics Limited
*
* This code is covered by the GPL.
*
* $Id: cfi_util.c,v 1.4 2004/07/14 08:38:44 dwmw2 Exp $
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/mtd/map.h>
#include <linux/mtd/cfi.h>
#include <linux/mtd/compatmac.h>
struct cfi_extquery *
cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
{
struct cfi_private *cfi = map->fldrv_priv;
__u32 base = 0; // cfi->chips[0].start;
int ofs_factor = cfi->interleave * cfi->device_type;
int i;
struct cfi_extquery *extp = NULL;
printk(" %s Extended Query Table at 0x%4.4X\n", name, adr);
if (!adr)
goto out;
/* Switch it into Query Mode */
cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
extp = kmalloc(size, GFP_KERNEL);
if (!extp) {
printk(KERN_ERR "Failed to allocate memory\n");
goto out;
}
/* Read in the Extended Query Table */
for (i=0; i<size; i++) {
((unsigned char *)extp)[i] =
cfi_read_query(map, base+((adr+i)*ofs_factor));
}
if (extp->MajorVersion != '1' ||
(extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
printk(KERN_WARNING " Unknown %s Extended Query "
"version %c.%c.\n", name, extp->MajorVersion,
extp->MinorVersion);
kfree(extp);
extp = NULL;
goto out;
}
out:
/* Make sure it's in read mode */
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);
return extp;
}
EXPORT_SYMBOL(cfi_read_pri);
void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups)
{
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_fixup *f;
for (f=fixups; f->fixup; f++) {
if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) &&
((f->id == CFI_ID_ANY) || (f->id == cfi->id))) {
f->fixup(map, f->param);
}
}
}
EXPORT_SYMBOL(cfi_fixup);
MODULE_LICENSE("GPL");
/*
* $Id: chipreg.c,v 1.15 2003/05/21 15:15:05 dwmw2 Exp $
* $Id: chipreg.c,v 1.16 2003/05/29 09:36:15 dwmw2 Exp $
*
* Registration for chip drivers
*
......
......@@ -2,7 +2,7 @@
* Routines common to all CFI-type probes.
* (C) 2001-2003 Red Hat, Inc.
* GPL'd
* $Id: gen_probe.c,v 1.13 2003/06/25 11:50:37 dwmw2 Exp $
* $Id: gen_probe.c,v 1.19 2004/07/13 22:33:32 dwmw2 Exp $
*/
#include <linux/kernel.h>
......@@ -50,16 +50,15 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
EXPORT_SYMBOL(mtd_do_chip_probe);
struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
{
unsigned long base=0;
struct cfi_private cfi;
struct cfi_private *retcfi;
struct flchip chip[MAX_CFI_CHIPS];
int i;
unsigned long *chip_map;
int i, j, mapsize;
int max_chips;
memset(&cfi, 0, sizeof(cfi));
memset(&chip[0], 0, sizeof(chip));
/* Call the probetype-specific code with all permutations of
interleave and device type, etc. */
......@@ -80,46 +79,47 @@ struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe
return NULL;
}
#endif
chip[0].start = 0;
chip[0].state = FL_READY;
cfi.chipshift = cfi.cfiq->DevSize;
switch(cfi.interleave) {
#ifdef CFIDEV_INTERLEAVE_1
case 1:
break;
#endif
#ifdef CFIDEV_INTERLEAVE_2
case 2:
if (cfi_interleave_is_1(&cfi)) {
;
} else if (cfi_interleave_is_2(&cfi)) {
cfi.chipshift++;
break;
#endif
#ifdef CFIDEV_INTERLEAVE_4
case 4:
cfi.chipshift+=2;
break;
#endif
default:
} else if (cfi_interleave_is_4((&cfi))) {
cfi.chipshift += 2;
} else if (cfi_interleave_is_8(&cfi)) {
cfi.chipshift += 3;
} else {
BUG();
}
cfi.numchips = 1;
/*
* Allocate memory for bitmap of valid chips.
* Align bitmap storage size to full byte.
*/
max_chips = map->size >> cfi.chipshift;
mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
chip_map = kmalloc(mapsize, GFP_KERNEL);
if (!chip_map) {
printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
kfree(cfi.cfiq);
return NULL;
}
memset (chip_map, 0, mapsize);
set_bit(0, chip_map); /* Mark first chip valid */
/*
* Now probe for other chips, checking sensibly for aliases while
* we're at it. The new_chip probe above should have let the first
* chip in read mode.
*
* NOTE: Here, we're checking if there is room for another chip
* the same size within the mapping. Therefore,
* base + chipsize <= map->size is the correct thing to do,
* because, base + chipsize would be the _first_ byte of the
* next chip, not the one we're currently pondering.
*/
for (base = (1<<cfi.chipshift); base + (1<<cfi.chipshift) <= map->size;
base += (1<<cfi.chipshift))
cp->probe_chip(map, base, &chip[0], &cfi);
for (i = 1; i < max_chips; i++) {
cp->probe_chip(map, i << cfi.chipshift, chip_map, &cfi);
}
/*
* Now allocate the space for the structures we need to return to
......@@ -131,19 +131,26 @@ struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe
if (!retcfi) {
printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name);
kfree(cfi.cfiq);
kfree(chip_map);
return NULL;
}
memcpy(retcfi, &cfi, sizeof(cfi));
memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips);
/* Fix up the stuff that breaks when you move it */
for (i=0; i< retcfi->numchips; i++) {
init_waitqueue_head(&retcfi->chips[i].wq);
spin_lock_init(&retcfi->chips[i]._spinlock);
retcfi->chips[i].mutex = &retcfi->chips[i]._spinlock;
memset(&retcfi->chips[0], 0, sizeof(struct flchip) * cfi.numchips);
for (i = 0, j = 0; (j < cfi.numchips) && (i < max_chips); i++) {
if(test_bit(i, chip_map)) {
struct flchip *pchip = &retcfi->chips[j++];
pchip->start = (i << cfi.chipshift);
pchip->state = FL_READY;
init_waitqueue_head(&pchip->wq);
spin_lock_init(&pchip->_spinlock);
pchip->mutex = &pchip->_spinlock;
}
}
kfree(chip_map);
return retcfi;
}
......@@ -151,131 +158,27 @@ struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe
static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
struct cfi_private *cfi)
{
switch (map->buswidth) {
#ifdef CFIDEV_BUSWIDTH_1
case CFIDEV_BUSWIDTH_1:
cfi->interleave = CFIDEV_INTERLEAVE_1;
cfi->device_type = CFI_DEVICETYPE_X8;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
cfi->device_type = CFI_DEVICETYPE_X16;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
break;
#endif /* CFIDEV_BUSWITDH_1 */
#ifdef CFIDEV_BUSWIDTH_2
case CFIDEV_BUSWIDTH_2:
#ifdef CFIDEV_INTERLEAVE_1
cfi->interleave = CFIDEV_INTERLEAVE_1;
cfi->device_type = CFI_DEVICETYPE_X16;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif /* CFIDEV_INTERLEAVE_1 */
#ifdef CFIDEV_INTERLEAVE_2
cfi->interleave = CFIDEV_INTERLEAVE_2;
cfi->device_type = CFI_DEVICETYPE_X8;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
cfi->device_type = CFI_DEVICETYPE_X16;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif /* CFIDEV_INTERLEAVE_2 */
break;
#endif /* CFIDEV_BUSWIDTH_2 */
#ifdef CFIDEV_BUSWIDTH_4
case CFIDEV_BUSWIDTH_4:
#if defined(CFIDEV_INTERLEAVE_1) && defined(SOMEONE_ACTUALLY_MAKES_THESE)
cfi->interleave = CFIDEV_INTERLEAVE_1;
cfi->device_type = CFI_DEVICETYPE_X32;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif /* CFIDEV_INTERLEAVE_1 */
#ifdef CFIDEV_INTERLEAVE_2
cfi->interleave = CFIDEV_INTERLEAVE_2;
#ifdef SOMEONE_ACTUALLY_MAKES_THESE
cfi->device_type = CFI_DEVICETYPE_X32;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif
cfi->device_type = CFI_DEVICETYPE_X16;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
cfi->device_type = CFI_DEVICETYPE_X8;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif /* CFIDEV_INTERLEAVE_2 */
#ifdef CFIDEV_INTERLEAVE_4
cfi->interleave = CFIDEV_INTERLEAVE_4;
#ifdef SOMEONE_ACTUALLY_MAKES_THESE
cfi->device_type = CFI_DEVICETYPE_X32;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif
cfi->device_type = CFI_DEVICETYPE_X16;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
cfi->device_type = CFI_DEVICETYPE_X8;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif /* CFIDEV_INTERLEAVE_4 */
break;
#endif /* CFIDEV_BUSWIDTH_4 */
#ifdef CFIDEV_BUSWIDTH_8
case CFIDEV_BUSWIDTH_8:
#if defined(CFIDEV_INTERLEAVE_2) && defined(SOMEONE_ACTUALLY_MAKES_THESE)
cfi->interleave = CFIDEV_INTERLEAVE_2;
cfi->device_type = CFI_DEVICETYPE_X32;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif /* CFIDEV_INTERLEAVE_2 */
#ifdef CFIDEV_INTERLEAVE_4
cfi->interleave = CFIDEV_INTERLEAVE_4;
#ifdef SOMEONE_ACTUALLY_MAKES_THESE
cfi->device_type = CFI_DEVICETYPE_X32;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif
cfi->device_type = CFI_DEVICETYPE_X16;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif /* CFIDEV_INTERLEAVE_4 */
#ifdef CFIDEV_INTERLEAVE_8
cfi->interleave = CFIDEV_INTERLEAVE_8;
cfi->device_type = CFI_DEVICETYPE_X16;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
cfi->device_type = CFI_DEVICETYPE_X8;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
#endif /* CFIDEV_INTERLEAVE_8 */
break;
#endif /* CFIDEV_BUSWIDTH_8 */
default:
printk(KERN_WARNING "genprobe_new_chip called with unsupported buswidth %d\n", map->buswidth);
return 0;
int min_chips = (map_bankwidth(map)/4?:1); /* At most 4-bytes wide. */
int max_chips = map_bankwidth(map); /* And minimum 1 */
int nr_chips, type;
for (nr_chips = min_chips; nr_chips <= max_chips; nr_chips <<= 1) {
if (!cfi_interleave_supported(nr_chips))
continue;
cfi->interleave = nr_chips;
for (type = 0; type < 3; type++) {
cfi->device_type = 1<<type;
if (cp->probe_chip(map, 0, NULL, cfi))
return 1;
}
}
return 0;
}
typedef struct mtd_info *cfi_cmdset_fn_t(struct map_info *, int);
extern cfi_cmdset_fn_t cfi_cmdset_0001;
......
......@@ -11,7 +11,7 @@
* not going to guess how to send commands to them, plus I expect they will
* all speak CFI..
*
* $Id: jedec.c,v 1.19 2003/05/29 09:25:23 dwmw2 Exp $
* $Id: jedec.c,v 1.20 2004/07/12 14:03:01 dwmw2 Exp $
*/
#include <linux/init.h>
......
This diff is collapsed.
/*
* Common code to handle map devices which are simple RAM
* (C) 2000 Red Hat. GPL'd.
* $Id: map_ram.c,v 1.17 2003/05/28 12:51:49 dwmw2 Exp $
* $Id: map_ram.c,v 1.19 2004/07/12 21:58:44 dwmw2 Exp $
*/
#include <linux/module.h>
......@@ -104,10 +104,15 @@ static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr)
/* Yeah, it's inefficient. Who cares? It's faster than a _real_
flash erase. */
struct map_info *map = (struct map_info *)mtd->priv;
map_word allff;
unsigned long i;
for (i=0; i<instr->len; i++)
map_write8(map, 0xFF, instr->addr + i);
allff = map_word_ff(map);
for (i=0; i<instr->len; i += map_bankwidth(map))
map_write(map, allff, instr->addr + i);
instr->state = MTD_ERASE_DONE;
if (instr->callback)
instr->callback(instr);
......
/*
* Common code to handle map devices which are simple ROM
* (C) 2000 Red Hat. GPL'd.
* $Id: map_rom.c,v 1.20 2003/05/28 12:51:49 dwmw2 Exp $
* $Id: map_rom.c,v 1.21 2004/07/12 14:06:01 dwmw2 Exp $
*/
#include <linux/module.h>
......
......@@ -4,7 +4,7 @@
* Copyright 2000,2001 David A. Schleef <ds@schleef.org>
* 2000,2001 Lineo, Inc.
*
* $Id: sharp.c,v 1.12 2003/05/28 15:39:52 dwmw2 Exp $
* $Id: sharp.c,v 1.13 2004/07/12 14:06:34 dwmw2 Exp $
*
* Devices supported:
* LH28F016SCT Symmetrical block flash memory, 2Mx8
......
# drivers/mtd/maps/Kconfig
# $Id: Kconfig,v 1.12 2003/06/23 07:38:11 dwmw2 Exp $
# $Id: Kconfig,v 1.29 2004/07/15 15:29:17 dwmw2 Exp $
menu "Mapping drivers for chip access"
depends on MTD!=n
......@@ -151,11 +151,11 @@ config MTD_AMD76XROM
BE VERY CAREFUL.
config MTD_ICH2ROM
tristate "BIOS flash chip on Intel Hub Controller 2"
config MTD_ICHXROM
tristate "BIOS flash chip on Intel Controller Hub 2/3/4/5"
depends on X86 && MTD_JEDECPROBE && MTD_COMPLEX_MAPPINGS
help
Support for treating the BIOS flash chip on ICH2 motherboards
Support for treating the BIOS flash chip on ICHX motherboards
as an MTD device - with this you can reprogram your BIOS.
BE VERY CAREFUL.
......@@ -177,7 +177,7 @@ config MTD_TSUNAMI
config MTD_LASAT
tristate "Flash chips on LASAT board"
depends on LASAT && MTD_CFI
depends on LASAT
help
Support for the flash chips on the Lasat 100 and 200 boards.
......@@ -210,6 +210,52 @@ config MTD_PB1XXX_USER
You can say 'Y' to both this and 'MTD_PB1XXX_BOOT' above, to use
both banks.
config MTD_PB1550
tristate "Flash devices on Alchemy PB1550 board"
depends on MIPS && MIPS_PB1550
help
Flash memory access on Alchemy Pb1550 board
config MTD_PB1550_BOOT
bool "PB1550 boot flash device"
depends on MTD_PB1550
help
Use the first of the two 64MiB flash banks on Pb1550 board.
You can say 'Y' to both this and 'MTD_PB1550_USER' below, to use
both banks.
config MTD_PB1550_USER
bool "PB1550 user flash device"
depends on MTD_PB1550
default y if MTD_PB1550_BOOT = n
help
Use the second of the two 64MiB flash banks on Pb1550 board.
You can say 'Y' to both this and 'MTD_PB1550_BOOT' above, to use
both banks.
config MTD_DB1550
tristate "Flash devices on Alchemy DB1550 board"
depends on MIPS && MIPS_DB1550
help
Flash memory access on Alchemy Db1550 board
config MTD_DB1550_BOOT
bool "DB1550 boot flash device"
depends on MTD_DB1550
help
Use the first of the two 64MiB flash banks on Db1550 board.
You can say 'Y' to both this and 'MTD_DB1550_USER' below, to use
both banks.
config MTD_DB1550_USER
bool "DB1550 user flash device"
depends on MTD_DB1550
default y if MTD_DB1550_BOOT = n
help
Use the second of the two 64MiB flash banks on Db1550 board.
You can say 'Y' to both this and 'MTD_DB1550_BOOT' above, to use
both banks.
config MTD_DILNETPC
tristate "CFI Flash device mapped on DIL/Net PC"
depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT
......@@ -235,6 +281,13 @@ config MTD_L440GX
BE VERY CAREFUL.
config MTD_SBC8240
tristate "Flash device on SBC8240"
depends on PPC32 && MTD_JEDECPROBE && 6xx && 8260
help
Flash access on the SBC8240 board from Wind River. See
<http://www.windriver.com/products/sbc8240/>
config MTD_TQM8XXL
tristate "CFI Flash device mapped on TQM8XXL"
depends on MTD_CFI && PPC32 && 8xx && TQM8xxL
......@@ -265,7 +318,7 @@ config MTD_MBX860
config MTD_DBOX2
tristate "CFI Flash device mapped on D-Box2"
depends on PPC32 && 8xx && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
depends on PPC32 && 8xx && DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
help
This enables access routines for the flash chips on the Nokia/Sagem
D-Box 2 board. If you have one of these boards and would like to use
......@@ -457,6 +510,13 @@ config MTD_CEIVA
PhotoMax Digital Picture Frame.
If you have such a device, say 'Y'.
config MTD_NOR_TOTO
tristate "NOR Flash device on TOTO board"
depends on ARM && ARCH_OMAP && OMAP_TOTO
help
This enables access to the NOR flash on the Texas Instruments
TOTO board.
config MTD_H720X
tristate "Hynix evaluation board mappings"
depends on ARM && MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
......@@ -464,6 +524,13 @@ config MTD_H720X
This enables access to the flash chips on the Hynix evaluation boards.
If you have such a board, say 'Y'.
config MTD_MPC1211
tristate "CFI Flash device mapped on Interface MPC-1211"
depends on SUPERH && SH_MPC1211 && MTD_CFI
help
This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
If you have such a board, say 'Y'.
# This needs CFI or JEDEC, depending on the cards found.
config MTD_PCI
tristate "PCI MTD driver"
......@@ -491,11 +558,26 @@ config MTD_UCLINUX
config MTD_WRSBC8260
tristate "Map driver for WindRiver PowerQUICC II MPC82xx board"
depends on MTD_PARTITIONS && SBC82xx
depends on (SBC82xx || SBC8560)
select MTD_PARTITIONS
select MTD_MAP_BANK_WIDTH_4
select MTD_MAP_BANK_WIDTH_1
select MTD_CFI_I1
select MTD_CFI_I4
help
Map driver for WindRiver PowerQUICC II MPC82xx board. Drives
all three flash regions on CS0, CS1 and CS6 if they are configured
correctly by the boot loader.
config MTD_DMV182
tristate "Map driver for Dy-4 SVME/DMV-182 board."
depends on DMV182
select MTD_PARTITIONS
select MTD_MAP_BANK_WIDTH_32
select MTD_CFI_I8
select MTD_CFI_AMDSTD
help
Map driver for Dy-4 SVME/DMV-182 board.
endmenu
#
# linux/drivers/maps/Makefile
#
# $Id: Makefile.common,v 1.2 2003/05/28 10:48:41 dwmw2 Exp $
# $Id: Makefile.common,v 1.14 2004/07/12 16:07:31 dwmw2 Exp $
ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
obj-$(CONFIG_MTD) += map_funcs.o
......@@ -19,7 +19,7 @@ obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o
obj-$(CONFIG_MTD_IQ80310) += iq80310.o
obj-$(CONFIG_MTD_L440GX) += l440gx.o
obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o
obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o
obj-$(CONFIG_MTD_MBX860) += mbx860.o
......@@ -42,6 +42,9 @@ obj-$(CONFIG_MTD_OCELOT) += ocelot.o
obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
obj-$(CONFIG_MTD_PCI) += pci.o
obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o
obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o
obj-$(CONFIG_MTD_PB1550) += pb1550-flash.o
obj-$(CONFIG_MTD_DB1550) += db1550-flash.o
obj-$(CONFIG_MTD_LASAT) += lasat.o
obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
obj-$(CONFIG_MTD_EDB7312) += edb7312.o
......@@ -55,5 +58,9 @@ obj-$(CONFIG_MTD_EBONY) += ebony.o
obj-$(CONFIG_MTD_BEECH) += beech-mtd.o
obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o
obj-$(CONFIG_MTD_H720X) += h720x-flash.o
obj-$(CONFIG_MTD_SBC8240) += sbc8240.o
obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o
obj-$(CONFIG_MTD_MPC1211) += mpc1211.o
obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
obj-$(CONFIG_MTD_DMV182) += dmv182.o
This diff is collapsed.
/*
* $Id: arctic-mtd.c,v 1.10 2003/06/02 16:37:59 trini Exp $
* $Id: arctic-mtd.c,v 1.11 2004/07/12 21:59:43 dwmw2 Exp $
*
* drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
* IBM 405LP Arctic boards.
......@@ -72,7 +72,7 @@
static struct map_info arctic_mtd_map = {
.name = NAME,
.size = SIZE,
.buswidth = BUSWIDTH,
.bankwidth = BUSWIDTH,
.phys = PADDR,
};
......
......@@ -2,7 +2,7 @@
* NV-RAM memory access on autcpu12
* (C) 2002 Thomas Gleixner (gleixner@autronix.de)
*
* $Id: autcpu12-nvram.c,v 1.5 2003/05/21 12:45:18 dwmw2 Exp $
* $Id: autcpu12-nvram.c,v 1.6 2004/07/12 21:59:43 dwmw2 Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -39,7 +39,7 @@ static struct mtd_info *sram_mtd;
struct map_info autcpu12_sram_map = {
.name = "SRAM",
.size = 32768,
.buswidth = 4,
.bankwidth = 4,
.phys = 0x12000000,
};
......
/*
* $Id: beech-mtd.c,v 1.7 2003/05/21 12:45:18 dwmw2 Exp $
* $Id: beech-mtd.c,v 1.8 2004/07/12 21:59:43 dwmw2 Exp $
*
* drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
* IBM 405LP Beech boards.
......@@ -51,7 +51,7 @@
static struct map_info beech_mtd_map = {
.name = NAME,
.size = SIZE,
.buswidth = BUSWIDTH,
.bankwidth = BUSWIDTH,
.phys = PADDR
};
......
This diff is collapsed.
......@@ -11,7 +11,7 @@
*
* (C) 2000 Nicolas Pitre <nico@cam.org>
*
* $Id: ceiva.c,v 1.8 2003/05/21 12:45:18 dwmw2 Exp $
* $Id: ceiva.c,v 1.10 2004/07/12 21:59:43 dwmw2 Exp $
*/
#include <linux/config.h>
......@@ -151,7 +151,7 @@ static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info
}
clps[i].map->virt = (unsigned long)clps[i].vbase;
clps[i].map->buswidth = clps[i].width;
clps[i].map->bankwidth = clps[i].width;
clps[i].map->size = clps[i].size;
simple_map_init(&clps[i].map);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment