Commit e8a89ceb authored by Linus Torvalds's avatar Linus Torvalds

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

* git://git.infradead.org/mtd-2.6: (79 commits)
  mtd: Remove obsolete <mtd/compatmac.h> include
  mtd: Update copyright notices
  jffs2: Update copyright notices
  mtd-physmap: add support users can assign the probe type in board files
  mtd: remove redwood map driver
  mxc_nand: Add v3 (i.MX51) Support
  mxc_nand: support 8bit ecc
  mxc_nand: fix correct_data function
  mxc_nand: add V1_V2 namespace to registers
  mxc_nand: factor out a check_int function
  mxc_nand: make some internally used functions overwriteable
  mxc_nand: rework get_dev_status
  mxc_nand: remove 0xe00 offset from registers
  mtd: denali: Add multi connected NAND support
  mtd: denali: Remove set_ecc_config function
  mtd: denali: Remove unuseful code in get_xx_nand_para functions
  mtd: denali: Remove device_info_tag structure
  mtd: m25p80: add support for the Winbond W25Q32 SPI flash chip
  mtd: m25p80: add support for the Intel/Numonyx {16,32,64}0S33B SPI flash chips
  mtd: m25p80: add support for the EON EN25P{32, 64} SPI flash chips
  ...

Fix up trivial conflicts in drivers/mtd/maps/{Kconfig,redwood.c} due to
redwood driver removal.
parents 8196867c 6ae0185f
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
* partitions = mtd partition list * partitions = mtd partition list
*/ */
#define NFC_PG_SIZE_256 0
#define NFC_PG_SIZE_512 1
#define NFC_PG_SIZE_OFFSET 9 #define NFC_PG_SIZE_OFFSET 9
#define NFC_NWIDTH_8 0 #define NFC_NWIDTH_8 0
...@@ -30,7 +28,6 @@ ...@@ -30,7 +28,6 @@
struct bf5xx_nand_platform { struct bf5xx_nand_platform {
/* NAND chip information */ /* NAND chip information */
unsigned short page_size;
unsigned short data_width; unsigned short data_width;
/* RD/WR strobe delay timing information, all times in SCLK cycles */ /* RD/WR strobe delay timing information, all times in SCLK cycles */
......
...@@ -311,15 +311,17 @@ config SM_FTL ...@@ -311,15 +311,17 @@ config SM_FTL
select MTD_BLKDEVS select MTD_BLKDEVS
select MTD_NAND_ECC select MTD_NAND_ECC
help help
This enables new and very EXPERMENTAL support for SmartMedia/xD This enables EXPERIMENTAL R/W support for SmartMedia/xD
FTL (Flash translation layer). FTL (Flash translation layer).
Write support isn't yet well tested, therefore this code IS likely to Write support is only lightly tested, therefore this driver
eat your card, so please don't use it together with valuable data. isn't recommended to use with valuable data (anyway if you have
Use readonly driver (CONFIG_SSFDC) instead. valuable data, do backups regardless of software/hardware you
use, because you never know what will eat your data...)
If you only need R/O access, you can use older R/O driver
(CONFIG_SSFDC)
config MTD_OOPS config MTD_OOPS
tristate "Log panic/oops to an MTD buffer" tristate "Log panic/oops to an MTD buffer"
depends on MTD
help help
This enables panic and oops messages to be logged to a circular This enables panic and oops messages to be logged to a circular
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
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
drivers/mtd/afs.c: ARM Flash Layout/Partitioning drivers/mtd/afs.c: ARM Flash Layout/Partitioning
Copyright (C) 2000 ARM Limited Copyright © 2000 ARM Limited
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <linux/mtd/xip.h> #include <linux/mtd/xip.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
#include <linux/mtd/cfi.h> #include <linux/mtd/cfi.h>
/* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */ /* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
...@@ -63,6 +62,8 @@ static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); ...@@ -63,6 +62,8 @@ static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_intelext_sync (struct mtd_info *); static void cfi_intelext_sync (struct mtd_info *);
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_intelext_is_locked(struct mtd_info *mtd, loff_t ofs,
uint64_t len);
#ifdef CONFIG_MTD_OTP #ifdef CONFIG_MTD_OTP
static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
...@@ -448,6 +449,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) ...@@ -448,6 +449,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
mtd->sync = cfi_intelext_sync; mtd->sync = cfi_intelext_sync;
mtd->lock = cfi_intelext_lock; mtd->lock = cfi_intelext_lock;
mtd->unlock = cfi_intelext_unlock; mtd->unlock = cfi_intelext_unlock;
mtd->is_locked = cfi_intelext_is_locked;
mtd->suspend = cfi_intelext_suspend; mtd->suspend = cfi_intelext_suspend;
mtd->resume = cfi_intelext_resume; mtd->resume = cfi_intelext_resume;
mtd->flags = MTD_CAP_NORFLASH; mtd->flags = MTD_CAP_NORFLASH;
...@@ -717,7 +719,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd, ...@@ -717,7 +719,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
chip = &newcfi->chips[0]; chip = &newcfi->chips[0];
for (i = 0; i < cfi->numchips; i++) { for (i = 0; i < cfi->numchips; i++) {
shared[i].writing = shared[i].erasing = NULL; shared[i].writing = shared[i].erasing = NULL;
spin_lock_init(&shared[i].lock); mutex_init(&shared[i].lock);
for (j = 0; j < numparts; j++) { for (j = 0; j < numparts; j++) {
*chip = cfi->chips[i]; *chip = cfi->chips[i];
chip->start += j << partshift; chip->start += j << partshift;
...@@ -886,7 +888,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr ...@@ -886,7 +888,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
*/ */
struct flchip_shared *shared = chip->priv; struct flchip_shared *shared = chip->priv;
struct flchip *contender; struct flchip *contender;
spin_lock(&shared->lock); mutex_lock(&shared->lock);
contender = shared->writing; contender = shared->writing;
if (contender && contender != chip) { if (contender && contender != chip) {
/* /*
...@@ -899,7 +901,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr ...@@ -899,7 +901,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
* get_chip returns success we're clear to go ahead. * get_chip returns success we're clear to go ahead.
*/ */
ret = mutex_trylock(&contender->mutex); ret = mutex_trylock(&contender->mutex);
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
if (!ret) if (!ret)
goto retry; goto retry;
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -914,7 +916,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr ...@@ -914,7 +916,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
mutex_unlock(&contender->mutex); mutex_unlock(&contender->mutex);
return ret; return ret;
} }
spin_lock(&shared->lock); mutex_lock(&shared->lock);
/* We should not own chip if it is already /* We should not own chip if it is already
* in FL_SYNCING state. Put contender and retry. */ * in FL_SYNCING state. Put contender and retry. */
...@@ -930,7 +932,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr ...@@ -930,7 +932,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
* on this chip. Sleep. */ * on this chip. Sleep. */
if (mode == FL_ERASING && shared->erasing if (mode == FL_ERASING && shared->erasing
&& shared->erasing->oldstate == FL_ERASING) { && shared->erasing->oldstate == FL_ERASING) {
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -944,7 +946,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr ...@@ -944,7 +946,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
shared->writing = chip; shared->writing = chip;
if (mode == FL_ERASING) if (mode == FL_ERASING)
shared->erasing = chip; shared->erasing = chip;
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
} }
ret = chip_ready(map, chip, adr, mode); ret = chip_ready(map, chip, adr, mode);
if (ret == -EAGAIN) if (ret == -EAGAIN)
...@@ -959,7 +961,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad ...@@ -959,7 +961,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
if (chip->priv) { if (chip->priv) {
struct flchip_shared *shared = chip->priv; struct flchip_shared *shared = chip->priv;
spin_lock(&shared->lock); mutex_lock(&shared->lock);
if (shared->writing == chip && chip->oldstate == FL_READY) { if (shared->writing == chip && chip->oldstate == FL_READY) {
/* We own the ability to write, but we're done */ /* We own the ability to write, but we're done */
shared->writing = shared->erasing; shared->writing = shared->erasing;
...@@ -967,7 +969,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad ...@@ -967,7 +969,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
/* give back ownership to who we loaned it from */ /* give back ownership to who we loaned it from */
struct flchip *loaner = shared->writing; struct flchip *loaner = shared->writing;
mutex_lock(&loaner->mutex); mutex_lock(&loaner->mutex);
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
put_chip(map, loaner, loaner->start); put_chip(map, loaner, loaner->start);
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
...@@ -985,11 +987,11 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad ...@@ -985,11 +987,11 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
* Don't let the switch below mess things up since * Don't let the switch below mess things up since
* we don't have ownership to resume anything. * we don't have ownership to resume anything.
*/ */
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
wake_up(&chip->wq); wake_up(&chip->wq);
return; return;
} }
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
} }
switch(chip->oldstate) { switch(chip->oldstate) {
...@@ -2139,6 +2141,13 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ...@@ -2139,6 +2141,13 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
return ret; return ret;
} }
static int cfi_intelext_is_locked(struct mtd_info *mtd, loff_t ofs,
uint64_t len)
{
return cfi_varsize_frob(mtd, do_getlockstatus_oneblock,
ofs, len, NULL) ? 1 : 0;
}
#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,
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/mtd/compatmac.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/cfi.h> #include <linux/mtd/cfi.h>
...@@ -417,16 +416,26 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) ...@@ -417,16 +416,26 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
*/ */
cfi_fixup_major_minor(cfi, extp); cfi_fixup_major_minor(cfi, extp);
/*
* Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
* see: http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_r20.pdf, page 19
* http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_100_20011201.pdf
* http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf
*/
if (extp->MajorVersion != '1' || if (extp->MajorVersion != '1' ||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) { (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '4'))) {
printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query " printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
"version %c.%c.\n", extp->MajorVersion, "version %c.%c (%#02x/%#02x).\n",
extp->MinorVersion); extp->MajorVersion, extp->MinorVersion,
extp->MajorVersion, extp->MinorVersion);
kfree(extp); kfree(extp);
kfree(mtd); kfree(mtd);
return NULL; return NULL;
} }
printk(KERN_INFO " Amd/Fujitsu Extended Query version %c.%c.\n",
extp->MajorVersion, extp->MinorVersion);
/* Install our own private info structure */ /* Install our own private info structure */
cfi->cmdset_priv = extp; cfi->cmdset_priv = extp;
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/cfi.h> #include <linux/mtd/cfi.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
......
...@@ -235,9 +235,9 @@ static int __xipram cfi_chip_setup(struct map_info *map, ...@@ -235,9 +235,9 @@ static int __xipram cfi_chip_setup(struct map_info *map,
cfi_qry_mode_off(base, map, cfi); cfi_qry_mode_off(base, map, cfi);
xip_allowed(base, map); xip_allowed(base, map);
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. Manufacturer ID %#08x Chip ID %#08x\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, cfi->mfr, cfi->id);
return 1; return 1;
} }
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/cfi.h> #include <linux/mtd/cfi.h>
#include <linux/mtd/compatmac.h>
int __xipram cfi_qry_present(struct map_info *map, __u32 base, int __xipram cfi_qry_present(struct map_info *map, __u32 base,
struct cfi_private *cfi) struct cfi_private *cfi)
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
static DEFINE_SPINLOCK(chip_drvs_lock); static DEFINE_SPINLOCK(chip_drvs_lock);
static LIST_HEAD(chip_drvs_list); static LIST_HEAD(chip_drvs_list);
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/compatmac.h>
static int map_absent_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int map_absent_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/compatmac.h>
static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/compatmac.h>
static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
......
/* /*
* Read flash partition table from command line * Read flash partition table from command line
* *
* Copyright 2002 SYSGO Real-Time Solutions GmbH * Copyright © 2002 SYSGO Real-Time Solutions GmbH
* Copyright © 2002-2010 David Woodhouse <dwmw2@infradead.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
* The format for the command line is as follows: * The format for the command line is as follows:
* *
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/mtd/compatmac.h> /* for min() in older kernels */
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/doc2000.h> #include <linux/mtd/doc2000.h>
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/doc2000.h> #include <linux/mtd/doc2000.h>
#include <linux/mtd/compatmac.h>
/* Where to look for the devices? */ /* Where to look for the devices? */
#ifndef CONFIG_MTD_DOCPROBE_ADDRESS #ifndef CONFIG_MTD_DOCPROBE_ADDRESS
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -639,8 +641,18 @@ static const struct spi_device_id m25p_ids[] = { ...@@ -639,8 +641,18 @@ static const struct spi_device_id m25p_ids[] = {
{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
{ "at26df321", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, { "at26df321", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },
/* EON -- en25pxx */
{ "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
/* Intel/Numonyx -- xxxs33b */
{ "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
{ "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) },
{ "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) },
/* Macronix */ /* Macronix */
{ "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) },
{ "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) },
{ "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) },
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
...@@ -680,6 +692,16 @@ static const struct spi_device_id m25p_ids[] = { ...@@ -680,6 +692,16 @@ static const struct spi_device_id m25p_ids[] = {
{ "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) },
{ "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) },
{ "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) },
{ "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) },
{ "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) },
{ "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) },
{ "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) },
{ "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) },
{ "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) },
{ "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) },
{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) },
{ "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) },
{ "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) },
{ "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) },
...@@ -694,6 +716,7 @@ static const struct spi_device_id m25p_ids[] = { ...@@ -694,6 +716,7 @@ static const struct spi_device_id m25p_ids[] = {
{ "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
{ "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
{ "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
/* Catalyst / On Semiconductor -- non-JEDEC */ /* Catalyst / On Semiconductor -- non-JEDEC */
...@@ -723,7 +746,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) ...@@ -723,7 +746,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
if (tmp < 0) { if (tmp < 0) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
dev_name(&spi->dev), tmp); dev_name(&spi->dev), tmp);
return NULL; return ERR_PTR(tmp);
} }
jedec = id[0]; jedec = id[0];
jedec = jedec << 8; jedec = jedec << 8;
...@@ -731,14 +754,6 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) ...@@ -731,14 +754,6 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
jedec = jedec << 8; jedec = jedec << 8;
jedec |= id[2]; jedec |= id[2];
/*
* Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants,
* which depend on technology process. Officially RDID command doesn't
* exist for non-JEDEC chips, but for compatibility they return ID 0.
*/
if (jedec == 0)
return NULL;
ext_jedec = id[3] << 8 | id[4]; ext_jedec = id[3] << 8 | id[4];
for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) { for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
...@@ -749,7 +764,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) ...@@ -749,7 +764,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
return &m25p_ids[tmp]; return &m25p_ids[tmp];
} }
} }
return NULL; return ERR_PTR(-ENODEV);
} }
...@@ -794,9 +809,8 @@ static int __devinit m25p_probe(struct spi_device *spi) ...@@ -794,9 +809,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
const struct spi_device_id *jid; const struct spi_device_id *jid;
jid = jedec_probe(spi); jid = jedec_probe(spi);
if (!jid) { if (IS_ERR(jid)) {
dev_info(&spi->dev, "non-JEDEC variant of %s\n", return PTR_ERR(jid);
id->name);
} else if (jid != id) { } else if (jid != id) {
/* /*
* JEDEC knows better, so overwrite platform ID. We * JEDEC knows better, so overwrite platform ID. We
...@@ -826,11 +840,12 @@ static int __devinit m25p_probe(struct spi_device *spi) ...@@ -826,11 +840,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
dev_set_drvdata(&spi->dev, flash); dev_set_drvdata(&spi->dev, flash);
/* /*
* Atmel and SST serial flash tend to power * Atmel, SST and Intel/Numonyx serial flash tend to power
* up with the software protection bits set * up with the software protection bits set
*/ */
if (info->jedec_id >> 16 == 0x1f || if (info->jedec_id >> 16 == 0x1f ||
info->jedec_id >> 16 == 0x89 ||
info->jedec_id >> 16 == 0xbf) { info->jedec_id >> 16 == 0xbf) {
write_enable(flash); write_enable(flash);
write_sr(flash, 0); write_sr(flash, 0);
......
...@@ -141,7 +141,7 @@ static int dataflash_waitready(struct spi_device *spi) ...@@ -141,7 +141,7 @@ static int dataflash_waitready(struct spi_device *spi)
*/ */
static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
{ {
struct dataflash *priv = (struct dataflash *)mtd->priv; struct dataflash *priv = mtd->priv;
struct spi_device *spi = priv->spi; struct spi_device *spi = priv->spi;
struct spi_transfer x = { .tx_dma = 0, }; struct spi_transfer x = { .tx_dma = 0, };
struct spi_message msg; struct spi_message msg;
...@@ -231,7 +231,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) ...@@ -231,7 +231,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf) size_t *retlen, u_char *buf)
{ {
struct dataflash *priv = (struct dataflash *)mtd->priv; struct dataflash *priv = mtd->priv;
struct spi_transfer x[2] = { { .tx_dma = 0, }, }; struct spi_transfer x[2] = { { .tx_dma = 0, }, };
struct spi_message msg; struct spi_message msg;
unsigned int addr; unsigned int addr;
...@@ -304,7 +304,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -304,7 +304,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t * retlen, const u_char * buf) size_t * retlen, const u_char * buf)
{ {
struct dataflash *priv = (struct dataflash *)mtd->priv; struct dataflash *priv = mtd->priv;
struct spi_device *spi = priv->spi; struct spi_device *spi = priv->spi;
struct spi_transfer x[2] = { { .tx_dma = 0, }, }; struct spi_transfer x[2] = { { .tx_dma = 0, }, };
struct spi_message msg; struct spi_message msg;
...@@ -515,7 +515,7 @@ static ssize_t otp_read(struct spi_device *spi, unsigned base, ...@@ -515,7 +515,7 @@ static ssize_t otp_read(struct spi_device *spi, unsigned base,
static int dataflash_read_fact_otp(struct mtd_info *mtd, static int dataflash_read_fact_otp(struct mtd_info *mtd,
loff_t from, size_t len, size_t *retlen, u_char *buf) loff_t from, size_t len, size_t *retlen, u_char *buf)
{ {
struct dataflash *priv = (struct dataflash *)mtd->priv; struct dataflash *priv = mtd->priv;
int status; int status;
/* 64 bytes, from 0..63 ... start at 64 on-chip */ /* 64 bytes, from 0..63 ... start at 64 on-chip */
...@@ -532,7 +532,7 @@ static int dataflash_read_fact_otp(struct mtd_info *mtd, ...@@ -532,7 +532,7 @@ static int dataflash_read_fact_otp(struct mtd_info *mtd,
static int dataflash_read_user_otp(struct mtd_info *mtd, static int dataflash_read_user_otp(struct mtd_info *mtd,
loff_t from, size_t len, size_t *retlen, u_char *buf) loff_t from, size_t len, size_t *retlen, u_char *buf)
{ {
struct dataflash *priv = (struct dataflash *)mtd->priv; struct dataflash *priv = mtd->priv;
int status; int status;
/* 64 bytes, from 0..63 ... start at 0 on-chip */ /* 64 bytes, from 0..63 ... start at 0 on-chip */
...@@ -553,7 +553,7 @@ static int dataflash_write_user_otp(struct mtd_info *mtd, ...@@ -553,7 +553,7 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
const size_t l = 4 + 64; const size_t l = 4 + 64;
uint8_t *scratch; uint8_t *scratch;
struct spi_transfer t; struct spi_transfer t;
struct dataflash *priv = (struct dataflash *)mtd->priv; struct dataflash *priv = mtd->priv;
int status; int status;
if (len > 64) if (len > 64)
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mtd/compatmac.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/mtdram.h> #include <linux/mtd/mtdram.h>
......
...@@ -98,7 +98,6 @@ ...@@ -98,7 +98,6 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/pmc551.h> #include <linux/mtd/pmc551.h>
#include <linux/mtd/compatmac.h>
static struct mtd_info *pmc551list; static struct mtd_info *pmc551list;
......
...@@ -454,7 +454,7 @@ static int __init sst25l_probe(struct spi_device *spi) ...@@ -454,7 +454,7 @@ static int __init sst25l_probe(struct spi_device *spi)
parts, nr_parts); parts, nr_parts);
} }
} else if (data->nr_parts) { } else if (data && data->nr_parts) {
dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
data->nr_parts, data->name); data->nr_parts, data->name);
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
The initial developer of the original code is David A. Hinds The initial developer of the original code is David A. Hinds
<dahinds@users.sourceforge.net>. Portions created by David A. Hinds <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
are Copyright (C) 1999 David A. Hinds. All Rights Reserved. are Copyright © 1999 David A. Hinds. All Rights Reserved.
Alternatively, the contents of this file may be used under the Alternatively, the contents of this file may be used under the
terms of the GNU General Public License version 2 (the "GPL"), in terms of the GNU General Public License version 2 (the "GPL"), in
......
/* /*
* inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL) * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
* *
* (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) * Copyright © 2002, Greg Ungerer (gerg@snapgear.com)
* *
* Based heavily on the nftlcore.c code which is: * Based heavily on the nftlcore.c code which is:
* (c) 1999 Machine Vision Holdings, Inc. * Copyright © 1999 Machine Vision Holdings, Inc.
* Author: David Woodhouse <dwmw2@infradead.org> * Copyright © 1999 David Woodhouse <dwmw2@infradead.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* inftlmount.c -- INFTL mount code with extensive checks. * inftlmount.c -- INFTL mount code with extensive checks.
* *
* Author: Greg Ungerer (gerg@snapgear.com) * Author: Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com) * Copyright © 2002-2003, Greg Ungerer (gerg@snapgear.com)
* *
* Based heavily on the nftlmount.c code which is: * Based heavily on the nftlmount.c code which is:
* Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A. * Copyright © 2000 Netgem S.A.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nftl.h> #include <linux/mtd/nftl.h>
#include <linux/mtd/inftl.h> #include <linux/mtd/inftl.h>
#include <linux/mtd/compatmac.h>
/* /*
* find_boot_record: Find the INFTL Media Header and its Spare copy which * find_boot_record: Find the INFTL Media Header and its Spare copy which
......
...@@ -98,7 +98,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) ...@@ -98,7 +98,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum; numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum;
for (i = 0; i < numchips; i++) { for (i = 0; i < numchips; i++) {
shared[i].writing = shared[i].erasing = NULL; shared[i].writing = shared[i].erasing = NULL;
spin_lock_init(&shared[i].lock); mutex_init(&shared[i].lock);
for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) {
*chip = lpddr->chips[i]; *chip = lpddr->chips[i];
chip->start += j << lpddr->chipshift; chip->start += j << lpddr->chipshift;
...@@ -217,7 +217,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode) ...@@ -217,7 +217,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
*/ */
struct flchip_shared *shared = chip->priv; struct flchip_shared *shared = chip->priv;
struct flchip *contender; struct flchip *contender;
spin_lock(&shared->lock); mutex_lock(&shared->lock);
contender = shared->writing; contender = shared->writing;
if (contender && contender != chip) { if (contender && contender != chip) {
/* /*
...@@ -230,7 +230,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode) ...@@ -230,7 +230,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
* get_chip returns success we're clear to go ahead. * get_chip returns success we're clear to go ahead.
*/ */
ret = mutex_trylock(&contender->mutex); ret = mutex_trylock(&contender->mutex);
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
if (!ret) if (!ret)
goto retry; goto retry;
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -245,7 +245,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode) ...@@ -245,7 +245,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
mutex_unlock(&contender->mutex); mutex_unlock(&contender->mutex);
return ret; return ret;
} }
spin_lock(&shared->lock); mutex_lock(&shared->lock);
/* We should not own chip if it is already in FL_SYNCING /* We should not own chip if it is already in FL_SYNCING
* state. Put contender and retry. */ * state. Put contender and retry. */
...@@ -261,7 +261,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode) ...@@ -261,7 +261,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
Must sleep in such a case. */ Must sleep in such a case. */
if (mode == FL_ERASING && shared->erasing if (mode == FL_ERASING && shared->erasing
&& shared->erasing->oldstate == FL_ERASING) { && shared->erasing->oldstate == FL_ERASING) {
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait); add_wait_queue(&chip->wq, &wait);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -275,7 +275,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode) ...@@ -275,7 +275,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
shared->writing = chip; shared->writing = chip;
if (mode == FL_ERASING) if (mode == FL_ERASING)
shared->erasing = chip; shared->erasing = chip;
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
} }
ret = chip_ready(map, chip, mode); ret = chip_ready(map, chip, mode);
...@@ -348,7 +348,7 @@ static void put_chip(struct map_info *map, struct flchip *chip) ...@@ -348,7 +348,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
{ {
if (chip->priv) { if (chip->priv) {
struct flchip_shared *shared = chip->priv; struct flchip_shared *shared = chip->priv;
spin_lock(&shared->lock); mutex_lock(&shared->lock);
if (shared->writing == chip && chip->oldstate == FL_READY) { if (shared->writing == chip && chip->oldstate == FL_READY) {
/* We own the ability to write, but we're done */ /* We own the ability to write, but we're done */
shared->writing = shared->erasing; shared->writing = shared->erasing;
...@@ -356,7 +356,7 @@ static void put_chip(struct map_info *map, struct flchip *chip) ...@@ -356,7 +356,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
/* give back the ownership */ /* give back the ownership */
struct flchip *loaner = shared->writing; struct flchip *loaner = shared->writing;
mutex_lock(&loaner->mutex); mutex_lock(&loaner->mutex);
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
put_chip(map, loaner); put_chip(map, loaner);
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
...@@ -374,11 +374,11 @@ static void put_chip(struct map_info *map, struct flchip *chip) ...@@ -374,11 +374,11 @@ static void put_chip(struct map_info *map, struct flchip *chip)
* Don't let the switch below mess things up since * Don't let the switch below mess things up since
* we don't have ownership to resume anything. * we don't have ownership to resume anything.
*/ */
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
wake_up(&chip->wq); wake_up(&chip->wq);
return; return;
} }
spin_unlock(&shared->lock); mutex_unlock(&shared->lock);
} }
switch (chip->oldstate) { switch (chip->oldstate) {
......
...@@ -319,14 +319,6 @@ config MTD_CFI_FLAGADM ...@@ -319,14 +319,6 @@ config MTD_CFI_FLAGADM
Mapping for the Flaga digital module. If you don't have one, ignore Mapping for the Flaga digital module. If you don't have one, ignore
this setting. this setting.
config MTD_REDWOOD
tristate "CFI Flash devices mapped on IBM Redwood"
depends on MTD_CFI
help
This enables access routines for the flash chips on the IBM
Redwood board. If you have one of these boards and would like to
use the flash chips on it, say 'Y'.
config MTD_SOLUTIONENGINE config MTD_SOLUTIONENGINE
tristate "CFI Flash device mapped on Hitachi SolutionEngine" tristate "CFI Flash device mapped on Hitachi SolutionEngine"
depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS
......
...@@ -44,7 +44,6 @@ obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o ...@@ -44,7 +44,6 @@ obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
obj-$(CONFIG_MTD_EDB7312) += edb7312.o obj-$(CONFIG_MTD_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_IMPA7) += impa7.o obj-$(CONFIG_MTD_IMPA7) += impa7.o
obj-$(CONFIG_MTD_FORTUNET) += fortunet.o obj-$(CONFIG_MTD_FORTUNET) += fortunet.o
obj-$(CONFIG_MTD_REDWOOD) += redwood.o
obj-$(CONFIG_MTD_UCLINUX) += uclinux.o obj-$(CONFIG_MTD_UCLINUX) += uclinux.o
obj-$(CONFIG_MTD_NETtel) += nettel.o obj-$(CONFIG_MTD_NETtel) += nettel.o
obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
......
...@@ -118,7 +118,7 @@ static void ixp4xx_copy_from(struct map_info *map, void *to, ...@@ -118,7 +118,7 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
*dest++ = BYTE1(data); *dest++ = BYTE1(data);
src += 2; src += 2;
len -= 2; len -= 2;
} }
if (len > 0) if (len > 0)
*dest++ = BYTE0(flash_read16(src)); *dest++ = BYTE0(flash_read16(src));
...@@ -185,6 +185,8 @@ static int ixp4xx_flash_probe(struct platform_device *dev) ...@@ -185,6 +185,8 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
{ {
struct flash_platform_data *plat = dev->dev.platform_data; struct flash_platform_data *plat = dev->dev.platform_data;
struct ixp4xx_flash_info *info; struct ixp4xx_flash_info *info;
const char *part_type = NULL;
int nr_parts = 0;
int err = -1; int err = -1;
if (!plat) if (!plat)
...@@ -218,9 +220,9 @@ static int ixp4xx_flash_probe(struct platform_device *dev) ...@@ -218,9 +220,9 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
*/ */
info->map.bankwidth = 2; info->map.bankwidth = 2;
info->map.name = dev_name(&dev->dev); info->map.name = dev_name(&dev->dev);
info->map.read = ixp4xx_read16, info->map.read = ixp4xx_read16;
info->map.write = ixp4xx_probe_write16, info->map.write = ixp4xx_probe_write16;
info->map.copy_from = ixp4xx_copy_from, info->map.copy_from = ixp4xx_copy_from;
info->res = request_mem_region(dev->resource->start, info->res = request_mem_region(dev->resource->start,
resource_size(dev->resource), resource_size(dev->resource),
...@@ -248,11 +250,28 @@ static int ixp4xx_flash_probe(struct platform_device *dev) ...@@ -248,11 +250,28 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
info->mtd->owner = THIS_MODULE; info->mtd->owner = THIS_MODULE;
/* Use the fast version */ /* Use the fast version */
info->map.write = ixp4xx_write16, info->map.write = ixp4xx_write16;
#ifdef CONFIG_MTD_PARTITIONS
nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions,
dev->resource->start);
#endif
if (nr_parts > 0) {
part_type = "dynamic";
} else {
info->partitions = plat->parts;
nr_parts = plat->nr_parts;
part_type = "static";
}
if (nr_parts == 0) {
printk(KERN_NOTICE "IXP4xx flash: no partition info "
"available, registering whole flash\n");
err = add_mtd_device(info->mtd);
} else {
printk(KERN_NOTICE "IXP4xx flash: using %s partition "
"definition\n", part_type);
err = add_mtd_partitions(info->mtd, info->partitions, nr_parts);
err = parse_mtd_partitions(info->mtd, probes, &info->partitions, dev->resource->start);
if (err > 0) {
err = add_mtd_partitions(info->mtd, info->partitions, err);
if(err) if(err)
printk(KERN_ERR "Could not parse partitions\n"); printk(KERN_ERR "Could not parse partitions\n");
} }
......
...@@ -106,12 +106,12 @@ static int physmap_flash_probe(struct platform_device *dev) ...@@ -106,12 +106,12 @@ static int physmap_flash_probe(struct platform_device *dev)
for (i = 0; i < dev->num_resources; i++) { for (i = 0; i < dev->num_resources; i++) {
printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n", 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)resource_size(&dev->resource[i]),
(unsigned long long)dev->resource[i].start); (unsigned long long)dev->resource[i].start);
if (!devm_request_mem_region(&dev->dev, if (!devm_request_mem_region(&dev->dev,
dev->resource[i].start, dev->resource[i].start,
dev->resource[i].end - dev->resource[i].start + 1, resource_size(&dev->resource[i]),
dev_name(&dev->dev))) { dev_name(&dev->dev))) {
dev_err(&dev->dev, "Could not reserve memory region\n"); dev_err(&dev->dev, "Could not reserve memory region\n");
err = -ENOMEM; err = -ENOMEM;
...@@ -120,7 +120,7 @@ static int physmap_flash_probe(struct platform_device *dev) ...@@ -120,7 +120,7 @@ static int physmap_flash_probe(struct platform_device *dev)
info->map[i].name = dev_name(&dev->dev); info->map[i].name = dev_name(&dev->dev);
info->map[i].phys = dev->resource[i].start; info->map[i].phys = dev->resource[i].start;
info->map[i].size = dev->resource[i].end - dev->resource[i].start + 1; info->map[i].size = resource_size(&dev->resource[i]);
info->map[i].bankwidth = physmap_data->width; info->map[i].bankwidth = physmap_data->width;
info->map[i].set_vpp = physmap_data->set_vpp; info->map[i].set_vpp = physmap_data->set_vpp;
info->map[i].pfow_base = physmap_data->pfow_base; info->map[i].pfow_base = physmap_data->pfow_base;
...@@ -136,8 +136,12 @@ static int physmap_flash_probe(struct platform_device *dev) ...@@ -136,8 +136,12 @@ static int physmap_flash_probe(struct platform_device *dev)
simple_map_init(&info->map[i]); simple_map_init(&info->map[i]);
probe_type = rom_probe_types; probe_type = rom_probe_types;
for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++) if (physmap_data->probe_type == NULL) {
info->mtd[i] = do_map_probe(*probe_type, &info->map[i]); for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
} else
info->mtd[i] = do_map_probe(physmap_data->probe_type, &info->map[i]);
if (info->mtd[i] == 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;
......
...@@ -353,7 +353,7 @@ static int __devinit of_flash_probe(struct of_device *dev, ...@@ -353,7 +353,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
&info->parts, 0); &info->parts, 0);
if (err < 0) { if (err < 0) {
of_free_probes(part_probe_types); of_free_probes(part_probe_types);
return err; goto err_out;
} }
of_free_probes(part_probe_types); of_free_probes(part_probe_types);
...@@ -361,14 +361,14 @@ static int __devinit of_flash_probe(struct of_device *dev, ...@@ -361,14 +361,14 @@ static int __devinit of_flash_probe(struct of_device *dev,
if (err == 0) { if (err == 0) {
err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts); err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
if (err < 0) if (err < 0)
return err; goto err_out;
} }
#endif #endif
if (err == 0) { if (err == 0) {
err = parse_obsolete_partitions(dev, info, dp); err = parse_obsolete_partitions(dev, info, dp);
if (err < 0) if (err < 0)
return err; goto err_out;
} }
if (err > 0) if (err > 0)
......
/*
* drivers/mtd/maps/redwood.c
*
* FLASH map for the IBM Redwood 4/5/6 boards.
*
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#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>
#include <asm/io.h>
#define WINDOW_ADDR 0xffc00000
#define WINDOW_SIZE 0x00400000
#define RW_PART0_OF 0
#define RW_PART0_SZ 0x10000
#define RW_PART1_OF RW_PART0_SZ
#define RW_PART1_SZ 0x200000 - 0x10000
#define RW_PART2_OF 0x200000
#define RW_PART2_SZ 0x10000
#define RW_PART3_OF 0x210000
#define RW_PART3_SZ 0x200000 - (0x10000 + 0x20000)
#define RW_PART4_OF 0x3e0000
#define RW_PART4_SZ 0x20000
static struct mtd_partition redwood_flash_partitions[] = {
{
.name = "Redwood OpenBIOS Vital Product Data",
.offset = RW_PART0_OF,
.size = RW_PART0_SZ,
.mask_flags = MTD_WRITEABLE /* force read-only */
},
{
.name = "Redwood kernel",
.offset = RW_PART1_OF,
.size = RW_PART1_SZ
},
{
.name = "Redwood OpenBIOS non-volatile storage",
.offset = RW_PART2_OF,
.size = RW_PART2_SZ,
.mask_flags = MTD_WRITEABLE /* force read-only */
},
{
.name = "Redwood filesystem",
.offset = RW_PART3_OF,
.size = RW_PART3_SZ
},
{
.name = "Redwood OpenBIOS",
.offset = RW_PART4_OF,
.size = RW_PART4_SZ,
.mask_flags = MTD_WRITEABLE /* force read-only */
}
};
struct map_info redwood_flash_map = {
.name = "IBM Redwood",
.size = WINDOW_SIZE,
.bankwidth = 2,
.phys = WINDOW_ADDR,
};
#define NUM_REDWOOD_FLASH_PARTITIONS ARRAY_SIZE(redwood_flash_partitions)
static struct mtd_info *redwood_mtd;
static int __init init_redwood_flash(void)
{
int err;
printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
WINDOW_SIZE, WINDOW_ADDR);
redwood_flash_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
if (!redwood_flash_map.virt) {
printk("init_redwood_flash: failed to ioremap\n");
return -EIO;
}
simple_map_init(&redwood_flash_map);
redwood_mtd = do_map_probe("cfi_probe",&redwood_flash_map);
if (redwood_mtd) {
redwood_mtd->owner = THIS_MODULE;
err = add_mtd_partitions(redwood_mtd,
redwood_flash_partitions,
NUM_REDWOOD_FLASH_PARTITIONS);
if (err) {
printk("init_redwood_flash: add_mtd_partitions failed\n");
iounmap(redwood_flash_map.virt);
}
return err;
}
iounmap(redwood_flash_map.virt);
return -ENXIO;
}
static void __exit cleanup_redwood_flash(void)
{
if (redwood_mtd) {
del_mtd_partitions(redwood_mtd);
/* moved iounmap after map_destroy - armin */
map_destroy(redwood_mtd);
iounmap((void *)redwood_flash_map.virt);
}
}
module_init(init_redwood_flash);
module_exit(cleanup_redwood_flash);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MontaVista Software <source@mvista.com>");
MODULE_DESCRIPTION("MTD map driver for the IBM Redwood reference boards");
/* /*
* (C) 2003 David Woodhouse <dwmw2@infradead.org> * Interface to Linux block layer for MTD 'translation layers'.
* *
* Interface to Linux 2.5 block layer for MTD 'translation layers'. * Copyright © 2003-2010 David Woodhouse <dwmw2@infradead.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*/ */
...@@ -245,6 +259,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -245,6 +259,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
switch (cmd) { switch (cmd) {
case BLKFLSBUF: case BLKFLSBUF:
ret = dev->tr->flush ? dev->tr->flush(dev) : 0; ret = dev->tr->flush ? dev->tr->flush(dev) : 0;
break;
default: default:
ret = -ENOTTY; ret = -ENOTTY;
} }
...@@ -409,13 +424,14 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) ...@@ -409,13 +424,14 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
BUG(); BUG();
} }
/* Stop new requests to arrive */
del_gendisk(old->disk);
if (old->disk_attributes) if (old->disk_attributes)
sysfs_remove_group(&disk_to_dev(old->disk)->kobj, sysfs_remove_group(&disk_to_dev(old->disk)->kobj,
old->disk_attributes); old->disk_attributes);
/* Stop new requests to arrive */
del_gendisk(old->disk);
/* Stop the thread */ /* Stop the thread */
kthread_stop(old->thread); kthread_stop(old->thread);
......
/* /*
* Direct MTD block device access * Direct MTD block device access
* *
* (C) 2000-2003 Nicolas Pitre <nico@fluxnic.net> * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> * Copyright © 2000-2003 Nicolas Pitre <nico@fluxnic.net>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/ */
#include <linux/fs.h> #include <linux/fs.h>
......
/* /*
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
*
* Simple read-only (writable only for RAM) mtdblock driver * Simple read-only (writable only for RAM) mtdblock driver
*
* Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/ */
#include <linux/init.h> #include <linux/init.h>
......
/* /*
* Character-device access to raw MTD devices. * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*/ */
...@@ -18,7 +32,7 @@ ...@@ -18,7 +32,7 @@
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h> #include <linux/mtd/map.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -675,6 +689,20 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) ...@@ -675,6 +689,20 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
break; break;
} }
case MEMISLOCKED:
{
struct erase_info_user einfo;
if (copy_from_user(&einfo, argp, sizeof(einfo)))
return -EFAULT;
if (!mtd->is_locked)
ret = -EOPNOTSUPP;
else
ret = mtd->is_locked(mtd, einfo.start, einfo.length);
break;
}
/* Legacy interface */ /* Legacy interface */
case MEMGETOOBSEL: case MEMGETOOBSEL:
{ {
...@@ -950,9 +978,34 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -950,9 +978,34 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
struct mtd_file_info *mfi = file->private_data; struct mtd_file_info *mfi = file->private_data;
struct mtd_info *mtd = mfi->mtd; struct mtd_info *mtd = mfi->mtd;
struct map_info *map = mtd->priv;
unsigned long start;
unsigned long off;
u32 len;
if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
off = vma->vm_pgoff << PAGE_SHIFT;
start = map->phys;
len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
start &= PAGE_MASK;
if ((vma->vm_end - vma->vm_start + off) > len)
return -EINVAL;
off += start;
vma->vm_pgoff = off >> PAGE_SHIFT;
vma->vm_flags |= VM_IO | VM_RESERVED;
#ifdef pgprot_noncached
if (file->f_flags & O_DSYNC || off >= __pa(high_memory))
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
#endif
if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
if (mtd->type == MTD_RAM || mtd->type == MTD_ROM)
return 0; return 0;
}
return -ENOSYS; return -ENOSYS;
#else #else
return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS; return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
......
/* /*
* MTD device concatenation layer * MTD device concatenation layer
* *
* (C) 2002 Robert Kaiser <rkaiser@sysgo.de> * Copyright © 2002 Robert Kaiser <rkaiser@sysgo.de>
* Copyright © 2002-2010 David Woodhouse <dwmw2@infradead.org>
* *
* NAND support by Christian Gan <cgan@iders.ca> * NAND support by Christian Gan <cgan@iders.ca>
* *
* This code is GPL * 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -540,10 +554,12 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ...@@ -540,10 +554,12 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
else else
size = len; size = len;
err = subdev->lock(subdev, ofs, size); if (subdev->lock) {
err = subdev->lock(subdev, ofs, size);
if (err) if (err)
break; break;
} else
err = -EOPNOTSUPP;
len -= size; len -= size;
if (len == 0) if (len == 0)
...@@ -578,10 +594,12 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ...@@ -578,10 +594,12 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
else else
size = len; size = len;
err = subdev->unlock(subdev, ofs, size); if (subdev->unlock) {
err = subdev->unlock(subdev, ofs, size);
if (err) if (err)
break; break;
} else
err = -EOPNOTSUPP;
len -= size; len -= size;
if (len == 0) if (len == 0)
......
...@@ -2,9 +2,23 @@ ...@@ -2,9 +2,23 @@
* Core registration and callback routines for MTD * Core registration and callback routines for MTD
* drivers and users. * drivers and users.
* *
* bdi bits are: * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
* Copyright © 2006 Red Hat, Inc. All Rights Reserved. * Copyright © 2006 Red Hat UK Limited
* Written by David Howells (dhowells@redhat.com) *
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -17,7 +31,6 @@ ...@@ -17,7 +31,6 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mtd/compatmac.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
......
/* /*
* MTD Oops/Panic logger * MTD Oops/Panic logger
* *
* Copyright (C) 2007 Nokia Corporation. All rights reserved. * Copyright © 2007 Nokia Corporation. All rights reserved.
* *
* Author: Richard Purdie <rpurdie@openedhand.com> * Author: Richard Purdie <rpurdie@openedhand.com>
* *
......
/* /*
* Simple MTD partitioning layer * Simple MTD partitioning layer
* *
* (C) 2000 Nicolas Pitre <nico@fluxnic.net> * Copyright © 2000 Nicolas Pitre <nico@fluxnic.net>
* Copyright © 2002 Thomas Gleixner <gleixner@linutronix.de>
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
* *
* This code is GPL * 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
* 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
* added support for read_oob, write_oob
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -17,7 +29,6 @@ ...@@ -17,7 +29,6 @@
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/compatmac.h>
/* Our partition linked list */ /* Our partition linked list */
static LIST_HEAD(mtd_partitions); static LIST_HEAD(mtd_partitions);
...@@ -264,6 +275,14 @@ static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ...@@ -264,6 +275,14 @@ static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
return part->master->unlock(part->master, ofs + part->offset, len); return part->master->unlock(part->master, ofs + part->offset, len);
} }
static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
struct mtd_part *part = PART(mtd);
if ((len + ofs) > mtd->size)
return -EINVAL;
return part->master->is_locked(part->master, ofs + part->offset, len);
}
static void part_sync(struct mtd_info *mtd) static void part_sync(struct mtd_info *mtd)
{ {
struct mtd_part *part = PART(mtd); struct mtd_part *part = PART(mtd);
...@@ -402,6 +421,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master, ...@@ -402,6 +421,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
slave->mtd.lock = part_lock; slave->mtd.lock = part_lock;
if (master->unlock) if (master->unlock)
slave->mtd.unlock = part_unlock; slave->mtd.unlock = part_unlock;
if (master->is_locked)
slave->mtd.is_locked = part_is_locked;
if (master->block_isbad) if (master->block_isbad)
slave->mtd.block_isbad = part_block_isbad; slave->mtd.block_isbad = part_block_isbad;
if (master->block_markbad) if (master->block_markbad)
......
/* MTD-based superblock management /* MTD-based superblock management
* *
* Copyright © 2001-2007 Red Hat, Inc. All Rights Reserved. * Copyright © 2001-2007 Red Hat, Inc. All Rights Reserved.
* Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
*
* Written by: David Howells <dhowells@redhat.com> * Written by: David Howells <dhowells@redhat.com>
* David Woodhouse <dwmw2@infradead.org> * David Woodhouse <dwmw2@infradead.org>
* *
......
...@@ -37,7 +37,6 @@ config MTD_SM_COMMON ...@@ -37,7 +37,6 @@ config MTD_SM_COMMON
config MTD_NAND_MUSEUM_IDS config MTD_NAND_MUSEUM_IDS
bool "Enable chip ids for obsolete ancient NAND devices" bool "Enable chip ids for obsolete ancient NAND devices"
depends on MTD_NAND
default n default n
help help
Enable this option only when your board has first generation Enable this option only when your board has first generation
...@@ -61,6 +60,7 @@ config MTD_NAND_DENALI ...@@ -61,6 +60,7 @@ config MTD_NAND_DENALI
config MTD_NAND_DENALI_SCRATCH_REG_ADDR config MTD_NAND_DENALI_SCRATCH_REG_ADDR
hex "Denali NAND size scratch register address" hex "Denali NAND size scratch register address"
default "0xFF108018" default "0xFF108018"
depends on MTD_NAND_DENALI
help help
Some platforms place the NAND chip size in a scratch register Some platforms place the NAND chip size in a scratch register
because (some versions of) the driver aren't able to automatically because (some versions of) the driver aren't able to automatically
...@@ -101,13 +101,13 @@ config MTD_NAND_AMS_DELTA ...@@ -101,13 +101,13 @@ config MTD_NAND_AMS_DELTA
config MTD_NAND_OMAP2 config MTD_NAND_OMAP2
tristate "NAND Flash device on OMAP2 and OMAP3" tristate "NAND Flash device on OMAP2 and OMAP3"
depends on ARM && MTD_NAND && (ARCH_OMAP2 || ARCH_OMAP3) depends on ARM && (ARCH_OMAP2 || ARCH_OMAP3)
help help
Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
config MTD_NAND_OMAP_PREFETCH config MTD_NAND_OMAP_PREFETCH
bool "GPMC prefetch support for NAND Flash device" bool "GPMC prefetch support for NAND Flash device"
depends on MTD_NAND && MTD_NAND_OMAP2 depends on MTD_NAND_OMAP2
default y default y
help help
The NAND device can be accessed for Read/Write using GPMC PREFETCH engine The NAND device can be accessed for Read/Write using GPMC PREFETCH engine
...@@ -146,7 +146,7 @@ config MTD_NAND_AU1550 ...@@ -146,7 +146,7 @@ config MTD_NAND_AU1550
config MTD_NAND_BF5XX config MTD_NAND_BF5XX
tristate "Blackfin on-chip NAND Flash Controller driver" tristate "Blackfin on-chip NAND Flash Controller driver"
depends on (BF54x || BF52x) && MTD_NAND depends on BF54x || BF52x
help help
This enables the Blackfin on-chip NAND flash controller This enables the Blackfin on-chip NAND flash controller
...@@ -236,7 +236,7 @@ config MTD_NAND_S3C2410_CLKSTOP ...@@ -236,7 +236,7 @@ config MTD_NAND_S3C2410_CLKSTOP
config MTD_NAND_BCM_UMI config MTD_NAND_BCM_UMI
tristate "NAND Flash support for BCM Reference Boards" tristate "NAND Flash support for BCM Reference Boards"
depends on ARCH_BCMRING && MTD_NAND depends on ARCH_BCMRING
help help
This enables the NAND flash controller on the BCM UMI block. This enables the NAND flash controller on the BCM UMI block.
...@@ -395,7 +395,7 @@ endchoice ...@@ -395,7 +395,7 @@ endchoice
config MTD_NAND_PXA3xx config MTD_NAND_PXA3xx
tristate "Support for NAND flash devices on PXA3xx" tristate "Support for NAND flash devices on PXA3xx"
depends on MTD_NAND && (PXA3xx || ARCH_MMP) depends on PXA3xx || ARCH_MMP
help help
This enables the driver for the NAND flash device found on This enables the driver for the NAND flash device found on
PXA3xx processors PXA3xx processors
...@@ -409,18 +409,18 @@ config MTD_NAND_PXA3xx_BUILTIN ...@@ -409,18 +409,18 @@ config MTD_NAND_PXA3xx_BUILTIN
config MTD_NAND_CM_X270 config MTD_NAND_CM_X270
tristate "Support for NAND Flash on CM-X270 modules" tristate "Support for NAND Flash on CM-X270 modules"
depends on MTD_NAND && MACH_ARMCORE depends on MACH_ARMCORE
config MTD_NAND_PASEMI config MTD_NAND_PASEMI
tristate "NAND support for PA Semi PWRficient" tristate "NAND support for PA Semi PWRficient"
depends on MTD_NAND && PPC_PASEMI depends on PPC_PASEMI
help help
Enables support for NAND Flash interface on PA Semi PWRficient Enables support for NAND Flash interface on PA Semi PWRficient
based boards based boards
config MTD_NAND_TMIO config MTD_NAND_TMIO
tristate "NAND Flash device on Toshiba Mobile IO Controller" tristate "NAND Flash device on Toshiba Mobile IO Controller"
depends on MTD_NAND && MFD_TMIO depends on MFD_TMIO
help help
Support for NAND flash connected to a Toshiba Mobile IO Support for NAND flash connected to a Toshiba Mobile IO
Controller in some PDAs, including the Sharp SL6000x. Controller in some PDAs, including the Sharp SL6000x.
...@@ -434,7 +434,6 @@ config MTD_NAND_NANDSIM ...@@ -434,7 +434,6 @@ config MTD_NAND_NANDSIM
config MTD_NAND_PLATFORM config MTD_NAND_PLATFORM
tristate "Support for generic platform NAND driver" tristate "Support for generic platform NAND driver"
depends on MTD_NAND
help help
This implements a generic NAND driver for on-SOC platform This implements a generic NAND driver for on-SOC platform
devices. You will need to provide platform-specific functions devices. You will need to provide platform-specific functions
...@@ -442,14 +441,14 @@ config MTD_NAND_PLATFORM ...@@ -442,14 +441,14 @@ config MTD_NAND_PLATFORM
config MTD_ALAUDA config MTD_ALAUDA
tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1" tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
depends on MTD_NAND && USB depends on USB
help help
These two (and possibly other) Alauda-based cardreaders for These two (and possibly other) Alauda-based cardreaders for
SmartMedia and xD allow raw flash access. SmartMedia and xD allow raw flash access.
config MTD_NAND_ORION config MTD_NAND_ORION
tristate "NAND Flash support for Marvell Orion SoC" tristate "NAND Flash support for Marvell Orion SoC"
depends on PLAT_ORION && MTD_NAND depends on PLAT_ORION
help help
This enables the NAND flash controller on Orion machines. This enables the NAND flash controller on Orion machines.
...@@ -458,7 +457,7 @@ config MTD_NAND_ORION ...@@ -458,7 +457,7 @@ config MTD_NAND_ORION
config MTD_NAND_FSL_ELBC config MTD_NAND_FSL_ELBC
tristate "NAND support for Freescale eLBC controllers" tristate "NAND support for Freescale eLBC controllers"
depends on MTD_NAND && PPC_OF depends on PPC_OF
help help
Various Freescale chips, including the 8313, include a NAND Flash Various Freescale chips, including the 8313, include a NAND Flash
Controller Module with built-in hardware ECC capabilities. Controller Module with built-in hardware ECC capabilities.
...@@ -467,7 +466,7 @@ config MTD_NAND_FSL_ELBC ...@@ -467,7 +466,7 @@ config MTD_NAND_FSL_ELBC
config MTD_NAND_FSL_UPM config MTD_NAND_FSL_UPM
tristate "Support for NAND on Freescale UPM" tristate "Support for NAND on Freescale UPM"
depends on MTD_NAND && (PPC_83xx || PPC_85xx) depends on PPC_83xx || PPC_85xx
select FSL_LBC select FSL_LBC
help help
Enables support for NAND Flash chips wired onto Freescale PowerPC Enables support for NAND Flash chips wired onto Freescale PowerPC
...@@ -482,7 +481,7 @@ config MTD_NAND_MPC5121_NFC ...@@ -482,7 +481,7 @@ config MTD_NAND_MPC5121_NFC
config MTD_NAND_MXC config MTD_NAND_MXC
tristate "MXC NAND support" tristate "MXC NAND support"
depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX51
help help
This enables the driver for the NAND flash controller on the This enables the driver for the NAND flash controller on the
MXC processors. MXC processors.
...@@ -495,7 +494,7 @@ config MTD_NAND_NOMADIK ...@@ -495,7 +494,7 @@ config MTD_NAND_NOMADIK
config MTD_NAND_SH_FLCTL config MTD_NAND_SH_FLCTL
tristate "Support for NAND on Renesas SuperH FLCTL" tristate "Support for NAND on Renesas SuperH FLCTL"
depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE) depends on SUPERH || ARCH_SHMOBILE
help help
Several Renesas SuperH CPU has FLCTL. This option enables support Several Renesas SuperH CPU has FLCTL. This option enables support
for NAND Flash using FLCTL. for NAND Flash using FLCTL.
...@@ -515,7 +514,7 @@ config MTD_NAND_TXX9NDFMC ...@@ -515,7 +514,7 @@ config MTD_NAND_TXX9NDFMC
config MTD_NAND_SOCRATES config MTD_NAND_SOCRATES
tristate "Support for NAND on Socrates board" tristate "Support for NAND on Socrates board"
depends on MTD_NAND && SOCRATES depends on SOCRATES
help help
Enables support for NAND Flash chips wired onto Socrates board. Enables support for NAND Flash chips wired onto Socrates board.
......
...@@ -364,7 +364,7 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) ...@@ -364,7 +364,7 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
} }
} }
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_CMDLINE_PARTS
static const char *part_probes[] = { "cmdlinepart", NULL }; static const char *part_probes[] = { "cmdlinepart", NULL };
#endif #endif
......
...@@ -20,9 +20,6 @@ ...@@ -20,9 +20,6 @@
* - DMA supported in ECC_HW * - DMA supported in ECC_HW
* - YAFFS tested as rootfs in both ECC_HW and ECC_SW * - YAFFS tested as rootfs in both ECC_HW and ECC_SW
* *
* TODO:
* Enable JFFS2 over NAND as rootfs
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
...@@ -206,7 +203,7 @@ static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd, ...@@ -206,7 +203,7 @@ static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd,
if (ctrl & NAND_CLE) if (ctrl & NAND_CLE)
bfin_write_NFC_CMD(cmd); bfin_write_NFC_CMD(cmd);
else else if (ctrl & NAND_ALE)
bfin_write_NFC_ADDR(cmd); bfin_write_NFC_ADDR(cmd);
SSYNC(); SSYNC();
} }
...@@ -218,9 +215,9 @@ static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd, ...@@ -218,9 +215,9 @@ static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd,
*/ */
static int bf5xx_nand_devready(struct mtd_info *mtd) static int bf5xx_nand_devready(struct mtd_info *mtd)
{ {
unsigned short val = bfin_read_NFC_IRQSTAT(); unsigned short val = bfin_read_NFC_STAT();
if ((val & NBUSYIRQ) == NBUSYIRQ) if ((val & NBUSY) == NBUSY)
return 1; return 1;
else else
return 0; return 0;
...@@ -317,18 +314,16 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat, ...@@ -317,18 +314,16 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat,
static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat, static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc) u_char *read_ecc, u_char *calc_ecc)
{ {
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); struct nand_chip *chip = mtd->priv;
struct bf5xx_nand_platform *plat = info->platform;
unsigned short page_size = (plat->page_size ? 512 : 256);
int ret; int ret;
ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
/* If page size is 512, correct second 256 bytes */ /* If ecc size is 512, correct second 256 bytes */
if (page_size == 512) { if (chip->ecc.size == 512) {
dat += 256; dat += 256;
read_ecc += 8; read_ecc += 3;
calc_ecc += 8; calc_ecc += 3;
ret |= bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); ret |= bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
} }
...@@ -344,13 +339,12 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd, ...@@ -344,13 +339,12 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd,
const u_char *dat, u_char *ecc_code) const u_char *dat, u_char *ecc_code)
{ {
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform; struct nand_chip *chip = mtd->priv;
u16 page_size = (plat->page_size ? 512 : 256);
u16 ecc0, ecc1; u16 ecc0, ecc1;
u32 code[2]; u32 code[2];
u8 *p; u8 *p;
/* first 4 bytes ECC code for 256 page size */ /* first 3 bytes ECC code for 256 page size */
ecc0 = bfin_read_NFC_ECC0(); ecc0 = bfin_read_NFC_ECC0();
ecc1 = bfin_read_NFC_ECC1(); ecc1 = bfin_read_NFC_ECC1();
...@@ -358,12 +352,11 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd, ...@@ -358,12 +352,11 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd,
dev_dbg(info->device, "returning ecc 0x%08x\n", code[0]); dev_dbg(info->device, "returning ecc 0x%08x\n", code[0]);
/* first 3 bytes in ecc_code for 256 page size */
p = (u8 *) code; p = (u8 *) code;
memcpy(ecc_code, p, 3); memcpy(ecc_code, p, 3);
/* second 4 bytes ECC code for 512 page size */ /* second 3 bytes ECC code for 512 ecc size */
if (page_size == 512) { if (chip->ecc.size == 512) {
ecc0 = bfin_read_NFC_ECC2(); ecc0 = bfin_read_NFC_ECC2();
ecc1 = bfin_read_NFC_ECC3(); ecc1 = bfin_read_NFC_ECC3();
code[1] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11); code[1] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11);
...@@ -483,8 +476,7 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd, ...@@ -483,8 +476,7 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
uint8_t *buf, int is_read) uint8_t *buf, int is_read)
{ {
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform; struct nand_chip *chip = mtd->priv;
unsigned short page_size = (plat->page_size ? 512 : 256);
unsigned short val; unsigned short val;
dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n", dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n",
...@@ -498,10 +490,10 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd, ...@@ -498,10 +490,10 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
*/ */
if (is_read) if (is_read)
invalidate_dcache_range((unsigned int)buf, invalidate_dcache_range((unsigned int)buf,
(unsigned int)(buf + page_size)); (unsigned int)(buf + chip->ecc.size));
else else
flush_dcache_range((unsigned int)buf, flush_dcache_range((unsigned int)buf,
(unsigned int)(buf + page_size)); (unsigned int)(buf + chip->ecc.size));
/* /*
* This register must be written before each page is * This register must be written before each page is
...@@ -510,6 +502,8 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd, ...@@ -510,6 +502,8 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
*/ */
bfin_write_NFC_RST(ECC_RST); bfin_write_NFC_RST(ECC_RST);
SSYNC(); SSYNC();
while (bfin_read_NFC_RST() & ECC_RST)
cpu_relax();
disable_dma(CH_NFC); disable_dma(CH_NFC);
clear_dma_irqstat(CH_NFC); clear_dma_irqstat(CH_NFC);
...@@ -520,13 +514,13 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd, ...@@ -520,13 +514,13 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
/* The DMAs have different size on BF52x and BF54x */ /* The DMAs have different size on BF52x and BF54x */
#ifdef CONFIG_BF52x #ifdef CONFIG_BF52x
set_dma_x_count(CH_NFC, (page_size >> 1)); set_dma_x_count(CH_NFC, (chip->ecc.size >> 1));
set_dma_x_modify(CH_NFC, 2); set_dma_x_modify(CH_NFC, 2);
val = DI_EN | WDSIZE_16; val = DI_EN | WDSIZE_16;
#endif #endif
#ifdef CONFIG_BF54x #ifdef CONFIG_BF54x
set_dma_x_count(CH_NFC, (page_size >> 2)); set_dma_x_count(CH_NFC, (chip->ecc.size >> 2));
set_dma_x_modify(CH_NFC, 4); set_dma_x_modify(CH_NFC, 4);
val = DI_EN | WDSIZE_32; val = DI_EN | WDSIZE_32;
#endif #endif
...@@ -548,12 +542,11 @@ static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd, ...@@ -548,12 +542,11 @@ static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
uint8_t *buf, int len) uint8_t *buf, int len)
{ {
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform; struct nand_chip *chip = mtd->priv;
unsigned short page_size = (plat->page_size ? 512 : 256);
dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len); dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len);
if (len == page_size) if (len == chip->ecc.size)
bf5xx_nand_dma_rw(mtd, buf, 1); bf5xx_nand_dma_rw(mtd, buf, 1);
else else
bf5xx_nand_read_buf(mtd, buf, len); bf5xx_nand_read_buf(mtd, buf, len);
...@@ -563,17 +556,32 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd, ...@@ -563,17 +556,32 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
const uint8_t *buf, int len) const uint8_t *buf, int len)
{ {
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform; struct nand_chip *chip = mtd->priv;
unsigned short page_size = (plat->page_size ? 512 : 256);
dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len); dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len);
if (len == page_size) if (len == chip->ecc.size)
bf5xx_nand_dma_rw(mtd, (uint8_t *)buf, 0); bf5xx_nand_dma_rw(mtd, (uint8_t *)buf, 0);
else else
bf5xx_nand_write_buf(mtd, buf, len); bf5xx_nand_write_buf(mtd, buf, len);
} }
static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int page)
{
bf5xx_nand_read_buf(mtd, buf, mtd->writesize);
bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize);
return 0;
}
static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf)
{
bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
}
/* /*
* System initialization functions * System initialization functions
*/ */
...@@ -627,15 +635,14 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info) ...@@ -627,15 +635,14 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
/* setup NFC_CTL register */ /* setup NFC_CTL register */
dev_info(info->device, dev_info(info->device,
"page_size=%d, data_width=%d, wr_dly=%d, rd_dly=%d\n", "data_width=%d, wr_dly=%d, rd_dly=%d\n",
(plat->page_size ? 512 : 256),
(plat->data_width ? 16 : 8), (plat->data_width ? 16 : 8),
plat->wr_dly, plat->rd_dly); plat->wr_dly, plat->rd_dly);
val = (plat->page_size << NFC_PG_SIZE_OFFSET) | val = (1 << NFC_PG_SIZE_OFFSET) |
(plat->data_width << NFC_NWIDTH_OFFSET) | (plat->data_width << NFC_NWIDTH_OFFSET) |
(plat->rd_dly << NFC_RDDLY_OFFSET) | (plat->rd_dly << NFC_RDDLY_OFFSET) |
(plat->rd_dly << NFC_WRDLY_OFFSET); (plat->wr_dly << NFC_WRDLY_OFFSET);
dev_dbg(info->device, "NFC_CTL is 0x%04x\n", val); dev_dbg(info->device, "NFC_CTL is 0x%04x\n", val);
bfin_write_NFC_CTL(val); bfin_write_NFC_CTL(val);
...@@ -698,6 +705,33 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev) ...@@ -698,6 +705,33 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
return 0; return 0;
} }
static int bf5xx_nand_scan(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
int ret;
ret = nand_scan_ident(mtd, 1);
if (ret)
return ret;
if (hardware_ecc) {
/*
* for nand with page size > 512B, think it as several sections with 512B
*/
if (likely(mtd->writesize >= 512)) {
chip->ecc.size = 512;
chip->ecc.bytes = 6;
} else {
chip->ecc.size = 256;
chip->ecc.bytes = 3;
bfin_write_NFC_CTL(bfin_read_NFC_CTL() & ~(1 << NFC_PG_SIZE_OFFSET));
SSYNC();
}
}
return nand_scan_tail(mtd);
}
/* /*
* bf5xx_nand_probe * bf5xx_nand_probe
* *
...@@ -783,27 +817,20 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev) ...@@ -783,27 +817,20 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
chip->badblock_pattern = &bootrom_bbt; chip->badblock_pattern = &bootrom_bbt;
chip->ecc.layout = &bootrom_ecclayout; chip->ecc.layout = &bootrom_ecclayout;
#endif #endif
if (plat->page_size == NFC_PG_SIZE_256) {
chip->ecc.bytes = 3;
chip->ecc.size = 256;
} else if (plat->page_size == NFC_PG_SIZE_512) {
chip->ecc.bytes = 6;
chip->ecc.size = 512;
}
chip->read_buf = bf5xx_nand_dma_read_buf; chip->read_buf = bf5xx_nand_dma_read_buf;
chip->write_buf = bf5xx_nand_dma_write_buf; chip->write_buf = bf5xx_nand_dma_write_buf;
chip->ecc.calculate = bf5xx_nand_calculate_ecc; chip->ecc.calculate = bf5xx_nand_calculate_ecc;
chip->ecc.correct = bf5xx_nand_correct_data; chip->ecc.correct = bf5xx_nand_correct_data;
chip->ecc.mode = NAND_ECC_HW; chip->ecc.mode = NAND_ECC_HW;
chip->ecc.hwctl = bf5xx_nand_enable_hwecc; chip->ecc.hwctl = bf5xx_nand_enable_hwecc;
chip->ecc.read_page_raw = bf5xx_nand_read_page_raw;
chip->ecc.write_page_raw = bf5xx_nand_write_page_raw;
} else { } else {
chip->ecc.mode = NAND_ECC_SOFT; chip->ecc.mode = NAND_ECC_SOFT;
} }
/* scan hardware nand chip and setup mtd info data struct */ /* scan hardware nand chip and setup mtd info data struct */
if (nand_scan(mtd, 1)) { if (bf5xx_nand_scan(mtd)) {
err = -ENXIO; err = -ENXIO;
goto out_err_nand_scan; goto out_err_nand_scan;
} }
......
...@@ -311,7 +311,9 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd, ...@@ -311,7 +311,9 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
unsigned short ecc10[8]; unsigned short ecc10[8];
unsigned short *ecc16; unsigned short *ecc16;
u32 syndrome[4]; u32 syndrome[4];
u32 ecc_state;
unsigned num_errors, corrected; unsigned num_errors, corrected;
unsigned long timeo = jiffies + msecs_to_jiffies(100);
/* All bytes 0xff? It's an erased page; ignore its ECC. */ /* All bytes 0xff? It's an erased page; ignore its ECC. */
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
...@@ -361,6 +363,21 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd, ...@@ -361,6 +363,21 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
*/ */
davinci_nand_writel(info, NANDFCR_OFFSET, davinci_nand_writel(info, NANDFCR_OFFSET,
davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13)); davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13));
/*
* ECC_STATE field reads 0x3 (Error correction complete) immediately
* after setting the 4BITECC_ADD_CALC_START bit. So if you immediately
* begin trying to poll for the state, you may fall right out of your
* loop without any of the correction calculations having taken place.
* The recommendation from the hardware team is to wait till ECC_STATE
* reads less than 4, which means ECC HW has entered correction state.
*/
do {
ecc_state = (davinci_nand_readl(info,
NANDFSR_OFFSET) >> 8) & 0x0f;
cpu_relax();
} while ((ecc_state < 4) && time_before(jiffies, timeo));
for (;;) { for (;;) {
u32 fsr = davinci_nand_readl(info, NANDFSR_OFFSET); u32 fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
......
This diff is collapsed.
This diff is collapsed.
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/doc2000.h> #include <linux/mtd/doc2000.h>
#include <linux/mtd/compatmac.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/mtd/inftl.h> #include <linux/mtd/inftl.h>
...@@ -146,6 +145,7 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc) ...@@ -146,6 +145,7 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
uint8_t parity; uint8_t parity;
uint16_t ds[4], s[5], tmp, errval[8], syn[4]; uint16_t ds[4], s[5], tmp, errval[8], syn[4];
memset(syn, 0, sizeof(syn));
/* Convert the ecc bytes into words */ /* Convert the ecc bytes into words */
ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8); ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8);
ds[1] = ((ecc[5] & 0xfc) >> 2) | ((ecc[2] & 0x0f) << 6); ds[1] = ((ecc[5] & 0xfc) >> 2) | ((ecc[2] & 0x0f) << 6);
...@@ -169,9 +169,9 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc) ...@@ -169,9 +169,9 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)]; s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)];
} }
/* Calc s[i] = s[i] / alpha^(v + i) */ /* Calc syn[i] = s[i] / alpha^(v + i) */
for (i = 0; i < NROOTS; i++) { for (i = 0; i < NROOTS; i++) {
if (syn[i]) if (s[i])
syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i)); syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
} }
/* Call the decoder library */ /* Call the decoder library */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -85,6 +85,7 @@ struct nand_flash_dev nand_flash_ids[] = { ...@@ -85,6 +85,7 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 128MiB 3,3V 8-bit", 0xD1, 0, 128, 0, LP_OPTIONS}, {"NAND 128MiB 3,3V 8-bit", 0xD1, 0, 128, 0, LP_OPTIONS},
{"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, LP_OPTIONS16}, {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, LP_OPTIONS16},
{"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, LP_OPTIONS16}, {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, LP_OPTIONS16},
{"NAND 128MiB 1,8V 16-bit", 0xAD, 0, 128, 0, LP_OPTIONS16},
/* 2 Gigabit */ /* 2 Gigabit */
{"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS}, {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS},
...@@ -110,6 +111,9 @@ struct nand_flash_dev nand_flash_ids[] = { ...@@ -110,6 +111,9 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16}, {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16},
{"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16}, {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16},
/* 32 Gigabit */
{"NAND 4GiB 3,3V 8-bit", 0xD7, 0, 4096, 0, LP_OPTIONS16},
/* /*
* Renesas AND 1 Gigabit. Those chips do not support extended id and * Renesas AND 1 Gigabit. Those chips do not support extended id and
* have a strange page/block layout ! The chosen minimum erasesize is * have a strange page/block layout ! The chosen minimum erasesize is
......
...@@ -553,8 +553,8 @@ static uint64_t divide(uint64_t n, uint32_t d) ...@@ -553,8 +553,8 @@ static uint64_t divide(uint64_t n, uint32_t d)
*/ */
static int init_nandsim(struct mtd_info *mtd) static int init_nandsim(struct mtd_info *mtd)
{ {
struct nand_chip *chip = (struct nand_chip *)mtd->priv; struct nand_chip *chip = mtd->priv;
struct nandsim *ns = (struct nandsim *)(chip->priv); struct nandsim *ns = chip->priv;
int i, ret = 0; int i, ret = 0;
uint64_t remains; uint64_t remains;
uint64_t next_offset; uint64_t next_offset;
...@@ -1877,7 +1877,7 @@ static void switch_state(struct nandsim *ns) ...@@ -1877,7 +1877,7 @@ static void switch_state(struct nandsim *ns)
static u_char ns_nand_read_byte(struct mtd_info *mtd) static u_char ns_nand_read_byte(struct mtd_info *mtd)
{ {
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
u_char outb = 0x00; u_char outb = 0x00;
/* Sanity and correctness checks */ /* Sanity and correctness checks */
...@@ -1950,7 +1950,7 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd) ...@@ -1950,7 +1950,7 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd)
static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
{ {
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
/* Sanity and correctness checks */ /* Sanity and correctness checks */
if (!ns->lines.ce) { if (!ns->lines.ce) {
...@@ -2132,7 +2132,7 @@ static uint16_t ns_nand_read_word(struct mtd_info *mtd) ...@@ -2132,7 +2132,7 @@ static uint16_t ns_nand_read_word(struct mtd_info *mtd)
static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
{ {
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
/* Check that chip is expecting data input */ /* Check that chip is expecting data input */
if (!(ns->state & STATE_DATAIN_MASK)) { if (!(ns->state & STATE_DATAIN_MASK)) {
...@@ -2159,7 +2159,7 @@ static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) ...@@ -2159,7 +2159,7 @@ static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{ {
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
/* Sanity and correctness checks */ /* Sanity and correctness checks */
if (!ns->lines.ce) { if (!ns->lines.ce) {
...@@ -2352,7 +2352,7 @@ module_init(ns_init_module); ...@@ -2352,7 +2352,7 @@ module_init(ns_init_module);
*/ */
static void __exit ns_cleanup_module(void) static void __exit ns_cleanup_module(void)
{ {
struct nandsim *ns = (struct nandsim *)(((struct nand_chip *)nsmtd->priv)->priv); struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv;
int i; int i;
free_nandsim(ns); /* Free nandsim private resources */ free_nandsim(ns); /* Free nandsim private resources */
......
...@@ -91,7 +91,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) ...@@ -91,7 +91,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
} }
/* Scan to find existance of the device */ /* Scan to find existance of the device */
if (nand_scan(&data->mtd, 1)) { if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {
err = -ENXIO; err = -ENXIO;
goto out; goto out;
} }
......
...@@ -64,8 +64,8 @@ static inline void r852_write_reg_dword(struct r852_device *dev, ...@@ -64,8 +64,8 @@ static inline void r852_write_reg_dword(struct r852_device *dev,
/* returns pointer to our private structure */ /* returns pointer to our private structure */
static inline struct r852_device *r852_get_dev(struct mtd_info *mtd) static inline struct r852_device *r852_get_dev(struct mtd_info *mtd)
{ {
struct nand_chip *chip = (struct nand_chip *)mtd->priv; struct nand_chip *chip = mtd->priv;
return (struct r852_device *)chip->priv; return chip->priv;
} }
...@@ -380,7 +380,7 @@ void r852_cmdctl(struct mtd_info *mtd, int dat, unsigned int ctrl) ...@@ -380,7 +380,7 @@ void r852_cmdctl(struct mtd_info *mtd, int dat, unsigned int ctrl)
*/ */
int r852_wait(struct mtd_info *mtd, struct nand_chip *chip) int r852_wait(struct mtd_info *mtd, struct nand_chip *chip)
{ {
struct r852_device *dev = (struct r852_device *)chip->priv; struct r852_device *dev = chip->priv;
unsigned long timeout; unsigned long timeout;
int status; int status;
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/rslib.h> #include <linux/rslib.h>
#include <linux/bitrev.h> #include <linux/bitrev.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mtd/compatmac.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
......
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