Merge git://git.infradead.org/mtd-2.6

* git://git.infradead.org/mtd-2.6: (120 commits)
  [MTD] Fix mtdoops.c compilation
  [MTD] [NOR] fix startup lock when using multiple nor flash chips
  [MTD] [DOC200x] eccbuf is statically defined and always evaluate to true
  [MTD] Fix maps/physmap.c compilation with CONFIG_PM
  [MTD] onenand: Add panic_write function to the onenand driver
  [MTD] mtdoops: Use the panic_write function when present
  [MTD] Add mtd panic_write function pointer
  [MTD] [NAND] Freescale enhanced Local Bus Controller FCM NAND support.
  [MTD] physmap.c: Add support for multiple resources
  [MTD] [NAND] Fix misparenthesization introduced by commit 78b65179...
  [MTD] [NAND] Fix Blackfin NFC ECC calculating bug with page size 512 bytes
  [MTD] [NAND] Remove wrong operation in PM function of the BF54x NFC driver
  [MTD] [NAND] Remove unused variable in plat_nand_remove
  [MTD] Unlocking all Intel flash that is locked on power up.
  [MTD] [NAND] at91_nand: Make mtdparts option can override board info
  [MTD] mtdoops: Various minor cleanups
  [MTD] mtdoops: Ensure sequential write to the buffer
  [MTD] mtdoops: Perform write operations in a workqueue
  [MTD] mtdoops: Add further error return code checking
  [MTD] [NOR] Test devtype, not definition in flash_probe(), drivers/mtd/devices/lart.c
  ...
This commit is contained in:
Linus Torvalds
2008-02-07 10:20:31 -08:00
66 changed files with 4871 additions and 2108 deletions
+11
View File
@@ -150,6 +150,14 @@ config MTD_AFS_PARTS
for your particular device. It won't happen automatically. The for your particular device. It won't happen automatically. The
'armflash' map driver (CONFIG_MTD_ARMFLASH) does this, for example. 'armflash' map driver (CONFIG_MTD_ARMFLASH) does this, for example.
config MTD_OF_PARTS
tristate "Flash partition map based on OF description"
depends on PPC_OF && MTD_PARTITIONS
help
This provides a partition parsing function which derives
the partition map from the children of the flash node,
as described in Documentation/powerpc/booting-without-of.txt.
comment "User Modules And Translation Layers" comment "User Modules And Translation Layers"
config MTD_CHAR config MTD_CHAR
@@ -286,6 +294,9 @@ config MTD_OOPS
buffer in a flash partition where it can be read back at some buffer in a flash partition where it can be read back at some
later point. later point.
To use, add console=ttyMTDx to the kernel command line,
where x is the MTD device number to use.
source "drivers/mtd/chips/Kconfig" source "drivers/mtd/chips/Kconfig"
source "drivers/mtd/maps/Kconfig" source "drivers/mtd/maps/Kconfig"
+1
View File
@@ -11,6 +11,7 @@ obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
# 'Users' - code which presents functionality to userspace. # 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_CHAR) += mtdchar.o obj-$(CONFIG_MTD_CHAR) += mtdchar.o
+70 -6
View File
@@ -50,6 +50,7 @@
#define I82802AC 0x00ac #define I82802AC 0x00ac
#define MANUFACTURER_ST 0x0020 #define MANUFACTURER_ST 0x0020
#define M50LPW080 0x002F #define M50LPW080 0x002F
#define AT49BV640D 0x02de
static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -157,6 +158,47 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
} }
#endif #endif
/* Atmel chips don't use the same PRI format as Intel chips */
static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_intelext *extp = cfi->cmdset_priv;
struct cfi_pri_atmel atmel_pri;
uint32_t features = 0;
/* Reverse byteswapping */
extp->FeatureSupport = cpu_to_le32(extp->FeatureSupport);
extp->BlkStatusRegMask = cpu_to_le16(extp->BlkStatusRegMask);
extp->ProtRegAddr = cpu_to_le16(extp->ProtRegAddr);
memcpy(&atmel_pri, extp, sizeof(atmel_pri));
memset((char *)extp + 5, 0, sizeof(*extp) - 5);
printk(KERN_ERR "atmel Features: %02x\n", atmel_pri.Features);
if (atmel_pri.Features & 0x01) /* chip erase supported */
features |= (1<<0);
if (atmel_pri.Features & 0x02) /* erase suspend supported */
features |= (1<<1);
if (atmel_pri.Features & 0x04) /* program suspend supported */
features |= (1<<2);
if (atmel_pri.Features & 0x08) /* simultaneous operations supported */
features |= (1<<9);
if (atmel_pri.Features & 0x20) /* page mode read supported */
features |= (1<<7);
if (atmel_pri.Features & 0x40) /* queued erase supported */
features |= (1<<4);
if (atmel_pri.Features & 0x80) /* Protection bits supported */
features |= (1<<6);
extp->FeatureSupport = features;
/* burst write mode not supported */
cfi->cfiq->BufWriteTimeoutTyp = 0;
cfi->cfiq->BufWriteTimeoutMax = 0;
}
#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)
@@ -227,13 +269,20 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
/* /*
* Some chips power-up with all sectors locked by default. * Some chips power-up with all sectors locked by default.
*/ */
static void fixup_use_powerup_lock(struct mtd_info *mtd, void *param) static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param)
{ {
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
if (cfip->FeatureSupport&32) {
printk(KERN_INFO "Using auto-unlock on power-up/resume\n" ); printk(KERN_INFO "Using auto-unlock on power-up/resume\n" );
mtd->flags |= MTD_STUPID_LOCK; mtd->flags |= MTD_POWERUP_LOCK;
}
} }
static struct cfi_fixup cfi_fixup_table[] = { static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
#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
@@ -245,7 +294,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
#endif #endif
{ CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL },
{ CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL },
{ MANUFACTURER_INTEL, 0x891c, fixup_use_powerup_lock, NULL, }, { MANUFACTURER_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
@@ -277,7 +326,7 @@ read_pri_intelext(struct map_info *map, __u16 adr)
return NULL; return NULL;
if (extp->MajorVersion != '1' || if (extp->MajorVersion != '1' ||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) { (extp->MinorVersion < '0' || extp->MinorVersion > '5')) {
printk(KERN_ERR " Unknown Intel/Sharp Extended Query " printk(KERN_ERR " Unknown Intel/Sharp Extended Query "
"version %c.%c.\n", extp->MajorVersion, "version %c.%c.\n", extp->MajorVersion,
extp->MinorVersion); extp->MinorVersion);
@@ -752,6 +801,7 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
{ {
int ret; int ret;
DECLARE_WAITQUEUE(wait, current);
retry: retry:
if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING
@@ -808,6 +858,20 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
spin_unlock(contender->mutex); spin_unlock(contender->mutex);
} }
/* Check if we already have suspended erase
* on this chip. Sleep. */
if (mode == FL_ERASING && shared->erasing
&& shared->erasing->oldstate == FL_ERASING) {
spin_unlock(&shared->lock);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
spin_lock(chip->mutex);
goto retry;
}
/* We now own it */ /* We now own it */
shared->writing = chip; shared->writing = chip;
if (mode == FL_ERASING) if (mode == FL_ERASING)
@@ -2294,7 +2358,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
struct flchip *chip; struct flchip *chip;
int ret = 0; int ret = 0;
if ((mtd->flags & MTD_STUPID_LOCK) if ((mtd->flags & MTD_POWERUP_LOCK)
&& extp && (extp->FeatureSupport & (1 << 5))) && extp && (extp->FeatureSupport & (1 << 5)))
cfi_intelext_save_locks(mtd); cfi_intelext_save_locks(mtd);
@@ -2405,7 +2469,7 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
spin_unlock(chip->mutex); spin_unlock(chip->mutex);
} }
if ((mtd->flags & MTD_STUPID_LOCK) if ((mtd->flags & MTD_POWERUP_LOCK)
&& extp && (extp->FeatureSupport & (1 << 5))) && extp && (extp->FeatureSupport & (1 << 5)))
cfi_intelext_restore_locks(mtd); cfi_intelext_restore_locks(mtd);
} }
+10 -4
View File
@@ -185,6 +185,10 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
extp->TopBottom = 2; extp->TopBottom = 2;
else else
extp->TopBottom = 3; extp->TopBottom = 3;
/* burst write mode not supported */
cfi->cfiq->BufWriteTimeoutTyp = 0;
cfi->cfiq->BufWriteTimeoutMax = 0;
} }
static void fixup_use_secsi(struct mtd_info *mtd, void *param) static void fixup_use_secsi(struct mtd_info *mtd, void *param)
@@ -213,10 +217,11 @@ static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param)
{ {
mtd->lock = cfi_atmel_lock; mtd->lock = cfi_atmel_lock;
mtd->unlock = cfi_atmel_unlock; mtd->unlock = cfi_atmel_unlock;
mtd->flags |= MTD_STUPID_LOCK; mtd->flags |= MTD_POWERUP_LOCK;
} }
static struct cfi_fixup cfi_fixup_table[] = { static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
#ifdef AMD_BOOTLOC_BUG #ifdef AMD_BOOTLOC_BUG
{ CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL },
#endif #endif
@@ -229,7 +234,6 @@ static struct cfi_fixup cfi_fixup_table[] = {
#if !FORCE_WORD_WRITE #if !FORCE_WORD_WRITE
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
#endif #endif
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
static struct cfi_fixup jedec_fixup_table[] = { static struct cfi_fixup jedec_fixup_table[] = {
@@ -338,10 +342,12 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
/* 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 ==
CFI_INTERFACE_X8_BY_X16_ASYNC)) ||
/* 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 ==
CFI_INTERFACE_X16_BY_X32_ASYNC)))
{ {
cfi->addr_unlock1 = 0xaaa; cfi->addr_unlock1 = 0xaaa;
cfi->addr_unlock2 = 0x555; cfi->addr_unlock2 = 0x555;
+6 -6
View File
@@ -370,27 +370,27 @@ static void print_cfi_ident(struct cfi_ident *cfip)
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 CFI_INTERFACE_X8_ASYNC:
printk(" - x8-only asynchronous interface\n"); printk(" - x8-only asynchronous interface\n");
break; break;
case 1: case CFI_INTERFACE_X16_ASYNC:
printk(" - x16-only asynchronous interface\n"); printk(" - x16-only asynchronous interface\n");
break; break;
case 2: case CFI_INTERFACE_X8_BY_X16_ASYNC:
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 CFI_INTERFACE_X32_ASYNC:
printk(" - x32-only asynchronous interface\n"); printk(" - x32-only asynchronous interface\n");
break; break;
case 4: case CFI_INTERFACE_X16_BY_X32_ASYNC:
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 CFI_INTERFACE_NOT_ALLOWED:
printk(" - Not Allowed / Reserved\n"); printk(" - Not Allowed / Reserved\n");
break; break;
+1 -1
View File
@@ -112,7 +112,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
max_chips = 1; max_chips = 1;
} }
mapsize = (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG; mapsize = sizeof(long) * ( (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG );
chip_map = kzalloc(mapsize, GFP_KERNEL); chip_map = kzalloc(mapsize, GFP_KERNEL);
if (!chip_map) { if (!chip_map) {
printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -9,7 +9,7 @@
* *
* mtdparts=<mtddef>[;<mtddef] * mtdparts=<mtddef>[;<mtddef]
* <mtddef> := <mtd-id>:<partdef>[,<partdef>] * <mtddef> := <mtd-id>:<partdef>[,<partdef>]
* <partdef> := <size>[@offset][<name>][ro] * <partdef> := <size>[@offset][<name>][ro][lk]
* <mtd-id> := unique name used in mapping driver/device (mtd->name) * <mtd-id> := unique name used in mapping driver/device (mtd->name)
* <size> := standard linux memsize OR "-" to denote all remaining space * <size> := standard linux memsize OR "-" to denote all remaining space
* <name> := '(' NAME ')' * <name> := '(' NAME ')'
@@ -143,6 +143,13 @@ static struct mtd_partition * newpart(char *s,
s += 2; s += 2;
} }
/* if lk is found do NOT unlock the MTD partition*/
if (strncmp(s, "lk", 2) == 0)
{
mask_flags |= MTD_POWERUP_LOCK;
s += 2;
}
/* test if more partitions are following */ /* test if more partitions are following */
if (*s == ',') if (*s == ',')
{ {
+2 -2
View File
@@ -632,7 +632,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
len = ((from | 0x1ff) + 1) - from; len = ((from | 0x1ff) + 1) - from;
/* The ECC will not be calculated correctly if less than 512 is read */ /* The ECC will not be calculated correctly if less than 512 is read */
if (len != 0x200 && eccbuf) if (len != 0x200)
printk(KERN_WARNING printk(KERN_WARNING
"ECC needs a full sector read (adr: %lx size %lx)\n", "ECC needs a full sector read (adr: %lx size %lx)\n",
(long) from, (long) len); (long) from, (long) len);
@@ -896,7 +896,7 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
/* Let the caller know we completed it */ /* Let the caller know we completed it */
*retlen += len; *retlen += len;
if (eccbuf) { {
unsigned char x[8]; unsigned char x[8];
size_t dummy; size_t dummy;
int ret; int ret;
+1 -1
View File
@@ -748,7 +748,7 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd); WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
/* On interleaved devices the flags for 2nd half 512 are before data */ /* On interleaved devices the flags for 2nd half 512 are before data */
if (eccbuf && before) if (before)
fto -= 2; fto -= 2;
/* issue the Serial Data In command to initial the Page Program process */ /* issue the Serial Data In command to initial the Page Program process */
+1 -1
View File
@@ -323,7 +323,7 @@ static int flash_probe (void)
/* put the flash back into command mode */ /* put the flash back into command mode */
write32 (DATA_TO_FLASH (READ_ARRAY),0x00000000); write32 (DATA_TO_FLASH (READ_ARRAY),0x00000000);
return (manufacturer == FLASH_MANUFACTURER && (devtype == FLASH_DEVICE_16mbit_TOP || FLASH_DEVICE_16mbit_BOTTOM)); return (manufacturer == FLASH_MANUFACTURER && (devtype == FLASH_DEVICE_16mbit_TOP || devtype == FLASH_DEVICE_16mbit_BOTTOM));
} }
/* /*
+1 -1
View File
@@ -420,7 +420,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
status = dataflash_waitready(priv->spi); status = dataflash_waitready(priv->spi);
/* Check result of the compare operation */ /* Check result of the compare operation */
if ((status & (1 << 6)) == 1) { if (status & (1 << 6)) {
printk(KERN_ERR "%s: compare page %u, err %d\n", printk(KERN_ERR "%s: compare page %u, err %d\n",
spi->dev.bus_id, pageaddr, status); spi->dev.bus_id, pageaddr, status);
remaining = 0; remaining = 0;
+1 -8
View File
@@ -110,13 +110,6 @@ config MTD_SUN_UFLASH
Sun Microsystems boardsets. This driver will require CFI support Sun Microsystems boardsets. This driver will require CFI support
in the kernel, so if you did not enable CFI previously, do that now. in the kernel, so if you did not enable CFI previously, do that now.
config MTD_PNC2000
tristate "CFI Flash device mapped on Photron PNC-2000"
depends on X86 && MTD_CFI && MTD_PARTITIONS
help
PNC-2000 is the name of Network Camera product from PHOTRON
Ltd. in Japan. It uses CFI-compliant flash.
config MTD_SC520CDP config MTD_SC520CDP
tristate "CFI Flash device mapped on AMD SC520 CDP" tristate "CFI Flash device mapped on AMD SC520 CDP"
depends on X86 && MTD_CFI && MTD_CONCAT depends on X86 && MTD_CFI && MTD_CONCAT
@@ -576,7 +569,7 @@ config MTD_BAST_MAXSIZE
default "4" default "4"
config MTD_SHARP_SL config MTD_SHARP_SL
bool "ROM mapped on Sharp SL Series" tristate "ROM mapped on Sharp SL Series"
depends on ARCH_PXA depends on ARCH_PXA
help help
This enables access to the flash chip on the Sharp SL Series of PDAs. This enables access to the flash chip on the Sharp SL Series of PDAs.
-1
View File
@@ -28,7 +28,6 @@ obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o
obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o
obj-$(CONFIG_MTD_PMC_MSP_RAMROOT)+= pmcmsp-ramroot.o obj-$(CONFIG_MTD_PMC_MSP_RAMROOT)+= pmcmsp-ramroot.o
obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o
+88 -40
View File
@@ -20,11 +20,15 @@
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/mtd/concat.h>
#include <asm/io.h> #include <asm/io.h>
#define MAX_RESOURCES 4
struct physmap_flash_info { struct physmap_flash_info {
struct mtd_info *mtd; struct mtd_info *mtd[MAX_RESOURCES];
struct map_info map; struct mtd_info *cmtd;
struct map_info map[MAX_RESOURCES];
struct resource *res; struct resource *res;
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
int nr_parts; int nr_parts;
@@ -32,11 +36,11 @@ struct physmap_flash_info {
#endif #endif
}; };
static int physmap_flash_remove(struct platform_device *dev) static int physmap_flash_remove(struct platform_device *dev)
{ {
struct physmap_flash_info *info; struct physmap_flash_info *info;
struct physmap_flash_data *physmap_data; struct physmap_flash_data *physmap_data;
int i;
info = platform_get_drvdata(dev); info = platform_get_drvdata(dev);
if (info == NULL) if (info == NULL)
@@ -45,24 +49,33 @@ static int physmap_flash_remove(struct platform_device *dev)
physmap_data = dev->dev.platform_data; physmap_data = dev->dev.platform_data;
if (info->mtd != NULL) { #ifdef CONFIG_MTD_CONCAT
if (info->cmtd != info->mtd[0]) {
del_mtd_device(info->cmtd);
mtd_concat_destroy(info->cmtd);
}
#endif
for (i = 0; i < MAX_RESOURCES; i++) {
if (info->mtd[i] != NULL) {
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
if (info->nr_parts) { if (info->nr_parts) {
del_mtd_partitions(info->mtd); del_mtd_partitions(info->mtd[i]);
kfree(info->parts); kfree(info->parts);
} else if (physmap_data->nr_parts) { } else if (physmap_data->nr_parts) {
del_mtd_partitions(info->mtd); del_mtd_partitions(info->mtd[i]);
} else { } else {
del_mtd_device(info->mtd); del_mtd_device(info->mtd[i]);
} }
#else #else
del_mtd_device(info->mtd); del_mtd_device(info->mtd[i]);
#endif #endif
map_destroy(info->mtd); map_destroy(info->mtd[i]);
} }
if (info->map.virt != NULL) if (info->map[i].virt != NULL)
iounmap(info->map.virt); iounmap(info->map[i].virt);
}
if (info->res != NULL) { if (info->res != NULL) {
release_resource(info->res); release_resource(info->res);
@@ -82,16 +95,14 @@ static int physmap_flash_probe(struct platform_device *dev)
struct physmap_flash_data *physmap_data; struct physmap_flash_data *physmap_data;
struct physmap_flash_info *info; struct physmap_flash_info *info;
const char **probe_type; const char **probe_type;
int err; int err = 0;
int i;
int devices_found = 0;
physmap_data = dev->dev.platform_data; physmap_data = dev->dev.platform_data;
if (physmap_data == NULL) if (physmap_data == NULL)
return -ENODEV; return -ENODEV;
printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
(unsigned long long)(dev->resource->end - dev->resource->start + 1),
(unsigned long long)dev->resource->start);
info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
if (info == NULL) { if (info == NULL) {
err = -ENOMEM; err = -ENOMEM;
@@ -100,8 +111,13 @@ static int physmap_flash_probe(struct platform_device *dev)
platform_set_drvdata(dev, info); platform_set_drvdata(dev, info);
info->res = request_mem_region(dev->resource->start, for (i = 0; i < dev->num_resources; i++) {
dev->resource->end - dev->resource->start + 1, printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
(unsigned long long)(dev->resource[i].end - dev->resource[i].start + 1),
(unsigned long long)dev->resource[i].start);
info->res = request_mem_region(dev->resource[i].start,
dev->resource[i].end - dev->resource[i].start + 1,
dev->dev.bus_id); dev->dev.bus_id);
if (info->res == NULL) { if (info->res == NULL) {
dev_err(&dev->dev, "Could not reserve memory region\n"); dev_err(&dev->dev, "Could not reserve memory region\n");
@@ -109,47 +125,69 @@ static int physmap_flash_probe(struct platform_device *dev)
goto err_out; goto err_out;
} }
info->map.name = dev->dev.bus_id; info->map[i].name = dev->dev.bus_id;
info->map.phys = dev->resource->start; info->map[i].phys = dev->resource[i].start;
info->map.size = dev->resource->end - dev->resource->start + 1; info->map[i].size = dev->resource[i].end - dev->resource[i].start + 1;
info->map.bankwidth = physmap_data->width; info->map[i].bankwidth = physmap_data->width;
info->map.set_vpp = physmap_data->set_vpp; info->map[i].set_vpp = physmap_data->set_vpp;
info->map.virt = ioremap(info->map.phys, info->map.size); info->map[i].virt = ioremap(info->map[i].phys, info->map[i].size);
if (info->map.virt == NULL) { if (info->map[i].virt == NULL) {
dev_err(&dev->dev, "Failed to ioremap flash region\n"); dev_err(&dev->dev, "Failed to ioremap flash region\n");
err = EIO; err = EIO;
goto err_out; goto err_out;
} }
simple_map_init(&info->map); simple_map_init(&info->map[i]);
probe_type = rom_probe_types; probe_type = rom_probe_types;
for (; info->mtd == NULL && *probe_type != NULL; probe_type++) for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
info->mtd = do_map_probe(*probe_type, &info->map); info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
if (info->mtd == NULL) { if (info->mtd[i] == NULL) {
dev_err(&dev->dev, "map_probe failed\n"); dev_err(&dev->dev, "map_probe failed\n");
err = -ENXIO; err = -ENXIO;
goto err_out; goto err_out;
} else {
devices_found++;
} }
info->mtd->owner = THIS_MODULE; info->mtd[i]->owner = THIS_MODULE;
}
if (devices_found == 1) {
info->cmtd = info->mtd[0];
} else if (devices_found > 1) {
/*
* We detected multiple devices. Concatenate them together.
*/
#ifdef CONFIG_MTD_CONCAT
info->cmtd = mtd_concat_create(info->mtd, devices_found, dev->dev.bus_id);
if (info->cmtd == NULL)
err = -ENXIO;
#else
printk(KERN_ERR "physmap-flash: multiple devices "
"found but MTD concat support disabled.\n");
err = -ENXIO;
#endif
}
if (err)
goto err_out;
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0); err = parse_mtd_partitions(info->cmtd, part_probe_types, &info->parts, 0);
if (err > 0) { if (err > 0) {
add_mtd_partitions(info->mtd, info->parts, err); add_mtd_partitions(info->cmtd, info->parts, err);
return 0; return 0;
} }
if (physmap_data->nr_parts) { if (physmap_data->nr_parts) {
printk(KERN_NOTICE "Using physmap partition information\n"); printk(KERN_NOTICE "Using physmap partition information\n");
add_mtd_partitions(info->mtd, physmap_data->parts, add_mtd_partitions(info->cmtd, physmap_data->parts,
physmap_data->nr_parts); physmap_data->nr_parts);
return 0; return 0;
} }
#endif #endif
add_mtd_device(info->mtd); add_mtd_device(info->cmtd);
return 0; return 0;
err_out: err_out:
@@ -162,9 +200,11 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state
{ {
struct physmap_flash_info *info = platform_get_drvdata(dev); struct physmap_flash_info *info = platform_get_drvdata(dev);
int ret = 0; int ret = 0;
int i;
if (info) if (info)
ret = info->mtd->suspend(info->mtd); for (i = 0; i < MAX_RESOURCES; i++)
ret |= info->mtd[i]->suspend(info->mtd[i]);
return ret; return ret;
} }
@@ -172,27 +212,35 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state
static int physmap_flash_resume(struct platform_device *dev) static int physmap_flash_resume(struct platform_device *dev)
{ {
struct physmap_flash_info *info = platform_get_drvdata(dev); struct physmap_flash_info *info = platform_get_drvdata(dev);
int i;
if (info) if (info)
info->mtd->resume(info->mtd); for (i = 0; i < MAX_RESOURCES; i++)
info->mtd[i]->resume(info->mtd[i]);
return 0; return 0;
} }
static void physmap_flash_shutdown(struct platform_device *dev) static void physmap_flash_shutdown(struct platform_device *dev)
{ {
struct physmap_flash_info *info = platform_get_drvdata(dev); struct physmap_flash_info *info = platform_get_drvdata(dev);
if (info && info->mtd->suspend(info->mtd) == 0) int i;
info->mtd->resume(info->mtd);
for (i = 0; i < MAX_RESOURCES; i++)
if (info && info->mtd[i]->suspend(info->mtd[i]) == 0)
info->mtd[i]->resume(info->mtd[i]);
} }
#else
#define physmap_flash_suspend NULL
#define physmap_flash_resume NULL
#define physmap_flash_shutdown NULL
#endif #endif
static struct platform_driver physmap_flash_driver = { static struct platform_driver physmap_flash_driver = {
.probe = physmap_flash_probe, .probe = physmap_flash_probe,
.remove = physmap_flash_remove, .remove = physmap_flash_remove,
#ifdef CONFIG_PM
.suspend = physmap_flash_suspend, .suspend = physmap_flash_suspend,
.resume = physmap_flash_resume, .resume = physmap_flash_resume,
.shutdown = physmap_flash_shutdown, .shutdown = physmap_flash_shutdown,
#endif
.driver = { .driver = {
.name = "physmap-flash", .name = "physmap-flash",
}, },
+27 -61
View File
@@ -80,64 +80,6 @@ static int parse_obsolete_partitions(struct of_device *dev,
return nr_parts; return nr_parts;
} }
static int __devinit parse_partitions(struct of_flash *info,
struct of_device *dev)
{
const char *partname;
static const char *part_probe_types[]
= { "cmdlinepart", "RedBoot", NULL };
struct device_node *dp = dev->node, *pp;
int nr_parts, i;
/* First look for RedBoot table or partitions on the command
* line, these take precedence over device tree information */
nr_parts = parse_mtd_partitions(info->mtd, part_probe_types,
&info->parts, 0);
if (nr_parts > 0) {
add_mtd_partitions(info->mtd, info->parts, nr_parts);
return 0;
}
/* First count the subnodes */
nr_parts = 0;
for (pp = dp->child; pp; pp = pp->sibling)
nr_parts++;
if (nr_parts == 0)
return parse_obsolete_partitions(dev, info, dp);
info->parts = kzalloc(nr_parts * sizeof(*info->parts),
GFP_KERNEL);
if (!info->parts)
return -ENOMEM;
for (pp = dp->child, i = 0; pp; pp = pp->sibling, i++) {
const u32 *reg;
int len;
reg = of_get_property(pp, "reg", &len);
if (!reg || (len != 2*sizeof(u32))) {
dev_err(&dev->dev, "Invalid 'reg' on %s\n",
dp->full_name);
kfree(info->parts);
info->parts = NULL;
return -EINVAL;
}
info->parts[i].offset = reg[0];
info->parts[i].size = reg[1];
partname = of_get_property(pp, "label", &len);
if (!partname)
partname = of_get_property(pp, "name", &len);
info->parts[i].name = (char *)partname;
if (of_get_property(pp, "read-only", &len))
info->parts[i].mask_flags = MTD_WRITEABLE;
}
return nr_parts;
}
#else /* MTD_PARTITIONS */ #else /* MTD_PARTITIONS */
#define OF_FLASH_PARTS(info) (0) #define OF_FLASH_PARTS(info) (0)
#define parse_partitions(info, dev) (0) #define parse_partitions(info, dev) (0)
@@ -212,6 +154,10 @@ static struct mtd_info * __devinit obsolete_probe(struct of_device *dev,
static int __devinit of_flash_probe(struct of_device *dev, static int __devinit of_flash_probe(struct of_device *dev,
const struct of_device_id *match) const struct of_device_id *match)
{ {
#ifdef CONFIG_MTD_PARTITIONS
static const char *part_probe_types[]
= { "cmdlinepart", "RedBoot", NULL };
#endif
struct device_node *dp = dev->node; struct device_node *dp = dev->node;
struct resource res; struct resource res;
struct of_flash *info; struct of_flash *info;
@@ -274,13 +220,33 @@ static int __devinit of_flash_probe(struct of_device *dev,
} }
info->mtd->owner = THIS_MODULE; info->mtd->owner = THIS_MODULE;
err = parse_partitions(info, dev); #ifdef CONFIG_MTD_PARTITIONS
/* First look for RedBoot table or partitions on the command
* line, these take precedence over device tree information */
err = parse_mtd_partitions(info->mtd, part_probe_types,
&info->parts, 0);
if (err < 0) if (err < 0)
goto err_out; return err;
#ifdef CONFIG_MTD_OF_PARTS
if (err == 0) {
err = of_mtd_parse_partitions(&dev->dev, info->mtd,
dp, &info->parts);
if (err < 0)
return err;
}
#endif
if (err == 0) {
err = parse_obsolete_partitions(dev, info, dp);
if (err < 0)
return err;
}
if (err > 0) if (err > 0)
add_mtd_partitions(info->mtd, OF_FLASH_PARTS(info), err); add_mtd_partitions(info->mtd, info->parts, err);
else else
#endif
add_mtd_device(info->mtd); add_mtd_device(info->mtd);
return 0; return 0;
-93
View File
@@ -1,93 +0,0 @@
/*
* pnc2000.c - mapper for Photron PNC-2000 board.
*
* Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
*
* This code is GPL
*
* $Id: pnc2000.c,v 1.18 2005/11/07 11:14:28 gleixner Exp $
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#define WINDOW_ADDR 0xbf000000
#define WINDOW_SIZE 0x00400000
/*
* MAP DRIVER STUFF
*/
static struct map_info pnc_map = {
.name = "PNC-2000",
.size = WINDOW_SIZE,
.bankwidth = 4,
.phys = 0xFFFFFFFF,
.virt = (void __iomem *)WINDOW_ADDR,
};
/*
* MTD 'PARTITIONING' STUFF
*/
static struct mtd_partition pnc_partitions[3] = {
{
.name = "PNC-2000 boot firmware",
.size = 0x20000,
.offset = 0
},
{
.name = "PNC-2000 kernel",
.size = 0x1a0000,
.offset = 0x20000
},
{
.name = "PNC-2000 filesystem",
.size = 0x240000,
.offset = 0x1c0000
}
};
/*
* This is the master MTD device for which all the others are just
* auto-relocating aliases.
*/
static struct mtd_info *mymtd;
static int __init init_pnc2000(void)
{
printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
simple_map_init(&pnc_map);
mymtd = do_map_probe("cfi_probe", &pnc_map);
if (mymtd) {
mymtd->owner = THIS_MODULE;
return add_mtd_partitions(mymtd, pnc_partitions, 3);
}
return -ENXIO;
}
static void __exit cleanup_pnc2000(void)
{
if (mymtd) {
del_mtd_partitions(mymtd);
map_destroy(mymtd);
}
}
module_init(init_pnc2000);
module_exit(cleanup_pnc2000);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp>");
MODULE_DESCRIPTION("MTD map driver for Photron PNC-2000 board");
+1 -1
View File
@@ -79,7 +79,7 @@ scb2_fixup_mtd(struct mtd_info *mtd)
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
/* barf if this doesn't look right */ /* barf if this doesn't look right */
if (cfi->cfiq->InterfaceDesc != 1) { if (cfi->cfiq->InterfaceDesc != CFI_INTERFACE_X16_ASYNC) {
printk(KERN_ERR MODNAME ": unsupported InterfaceDesc: %#x\n", printk(KERN_ERR MODNAME ": unsupported InterfaceDesc: %#x\n",
cfi->cfiq->InterfaceDesc); cfi->cfiq->InterfaceDesc);
return -1; return -1;
+1 -1
View File
@@ -248,9 +248,9 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
return -EBUSY; return -EBUSY;
} }
mutex_init(&new->lock);
list_add_tail(&new->list, &tr->devs); list_add_tail(&new->list, &tr->devs);
added: added:
mutex_init(&new->lock);
if (!tr->writesect) if (!tr->writesect)
new->readonly = 1; new->readonly = 1;
+6 -2
View File
@@ -481,6 +481,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
{ {
struct mtd_oob_buf buf; struct mtd_oob_buf buf;
struct mtd_oob_ops ops; struct mtd_oob_ops ops;
uint32_t retlen;
if(!(file->f_mode & 2)) if(!(file->f_mode & 2))
return -EPERM; return -EPERM;
@@ -520,8 +521,11 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
buf.start &= ~(mtd->oobsize - 1); buf.start &= ~(mtd->oobsize - 1);
ret = mtd->write_oob(mtd, buf.start, &ops); ret = mtd->write_oob(mtd, buf.start, &ops);
if (copy_to_user(argp + sizeof(uint32_t), &ops.oobretlen, if (ops.oobretlen > 0xFFFFFFFFU)
sizeof(uint32_t))) ret = -EOVERFLOW;
retlen = ops.oobretlen;
if (copy_to_user(&((struct mtd_oob_buf *)argp)->length,
&retlen, sizeof(buf.length)))
ret = -EFAULT; ret = -EFAULT;
kfree(ops.oobbuf); kfree(ops.oobbuf);

Some files were not shown because too many files have changed in this diff Show More