mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-04 04:02:26 +00:00
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.
This commit is contained in:
commit
e8a89cebdb
@ -15,8 +15,6 @@
|
||||
* partitions = mtd partition list
|
||||
*/
|
||||
|
||||
#define NFC_PG_SIZE_256 0
|
||||
#define NFC_PG_SIZE_512 1
|
||||
#define NFC_PG_SIZE_OFFSET 9
|
||||
|
||||
#define NFC_NWIDTH_8 0
|
||||
@ -30,7 +28,6 @@
|
||||
|
||||
struct bf5xx_nand_platform {
|
||||
/* NAND chip information */
|
||||
unsigned short page_size;
|
||||
unsigned short data_width;
|
||||
|
||||
/* RD/WR strobe delay timing information, all times in SCLK cycles */
|
||||
|
@ -311,15 +311,17 @@ config SM_FTL
|
||||
select MTD_BLKDEVS
|
||||
select MTD_NAND_ECC
|
||||
help
|
||||
This enables new and very EXPERMENTAL support for SmartMedia/xD
|
||||
This enables EXPERIMENTAL R/W support for SmartMedia/xD
|
||||
FTL (Flash translation layer).
|
||||
Write support isn't yet well tested, therefore this code IS likely to
|
||||
eat your card, so please don't use it together with valuable data.
|
||||
Use readonly driver (CONFIG_SSFDC) instead.
|
||||
Write support is only lightly tested, therefore this driver
|
||||
isn't recommended to use with valuable data (anyway if you have
|
||||
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
|
||||
tristate "Log panic/oops to an MTD buffer"
|
||||
depends on MTD
|
||||
help
|
||||
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
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <linux/mtd/xip.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/mtd/cfi.h>
|
||||
|
||||
/* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
|
||||
@ -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 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_is_locked(struct mtd_info *mtd, loff_t ofs,
|
||||
uint64_t len);
|
||||
#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_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)
|
||||
mtd->sync = cfi_intelext_sync;
|
||||
mtd->lock = cfi_intelext_lock;
|
||||
mtd->unlock = cfi_intelext_unlock;
|
||||
mtd->is_locked = cfi_intelext_is_locked;
|
||||
mtd->suspend = cfi_intelext_suspend;
|
||||
mtd->resume = cfi_intelext_resume;
|
||||
mtd->flags = MTD_CAP_NORFLASH;
|
||||
@ -717,7 +719,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
|
||||
chip = &newcfi->chips[0];
|
||||
for (i = 0; i < cfi->numchips; i++) {
|
||||
shared[i].writing = shared[i].erasing = NULL;
|
||||
spin_lock_init(&shared[i].lock);
|
||||
mutex_init(&shared[i].lock);
|
||||
for (j = 0; j < numparts; j++) {
|
||||
*chip = cfi->chips[i];
|
||||
chip->start += j << partshift;
|
||||
@ -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 *contender;
|
||||
spin_lock(&shared->lock);
|
||||
mutex_lock(&shared->lock);
|
||||
contender = shared->writing;
|
||||
if (contender && contender != chip) {
|
||||
/*
|
||||
@ -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.
|
||||
*/
|
||||
ret = mutex_trylock(&contender->mutex);
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
if (!ret)
|
||||
goto retry;
|
||||
mutex_unlock(&chip->mutex);
|
||||
@ -914,7 +916,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
|
||||
mutex_unlock(&contender->mutex);
|
||||
return ret;
|
||||
}
|
||||
spin_lock(&shared->lock);
|
||||
mutex_lock(&shared->lock);
|
||||
|
||||
/* We should not own chip if it is already
|
||||
* 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
|
||||
* on this chip. Sleep. */
|
||||
if (mode == FL_ERASING && shared->erasing
|
||||
&& shared->erasing->oldstate == FL_ERASING) {
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
mutex_unlock(&chip->mutex);
|
||||
@ -944,7 +946,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
|
||||
shared->writing = chip;
|
||||
if (mode == FL_ERASING)
|
||||
shared->erasing = chip;
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
}
|
||||
ret = chip_ready(map, chip, adr, mode);
|
||||
if (ret == -EAGAIN)
|
||||
@ -959,7 +961,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
|
||||
|
||||
if (chip->priv) {
|
||||
struct flchip_shared *shared = chip->priv;
|
||||
spin_lock(&shared->lock);
|
||||
mutex_lock(&shared->lock);
|
||||
if (shared->writing == chip && chip->oldstate == FL_READY) {
|
||||
/* We own the ability to write, but we're done */
|
||||
shared->writing = shared->erasing;
|
||||
@ -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 */
|
||||
struct flchip *loaner = shared->writing;
|
||||
mutex_lock(&loaner->mutex);
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
mutex_unlock(&chip->mutex);
|
||||
put_chip(map, loaner, loaner->start);
|
||||
mutex_lock(&chip->mutex);
|
||||
@ -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
|
||||
* we don't have ownership to resume anything.
|
||||
*/
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
wake_up(&chip->wq);
|
||||
return;
|
||||
}
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
}
|
||||
|
||||
switch(chip->oldstate) {
|
||||
@ -2139,6 +2141,13 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
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
|
||||
|
||||
typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/cfi.h>
|
||||
@ -417,16 +416,26 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
|
||||
*/
|
||||
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' ||
|
||||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
|
||||
(extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '4'))) {
|
||||
printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
|
||||
"version %c.%c.\n", extp->MajorVersion,
|
||||
extp->MinorVersion);
|
||||
"version %c.%c (%#02x/%#02x).\n",
|
||||
extp->MajorVersion, extp->MinorVersion,
|
||||
extp->MajorVersion, extp->MinorVersion);
|
||||
kfree(extp);
|
||||
kfree(mtd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printk(KERN_INFO " Amd/Fujitsu Extended Query version %c.%c.\n",
|
||||
extp->MajorVersion, extp->MinorVersion);
|
||||
|
||||
/* Install our own private info structure */
|
||||
cfi->cmdset_priv = extp;
|
||||
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/cfi.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 *);
|
||||
|
@ -235,9 +235,9 @@ static int __xipram cfi_chip_setup(struct map_info *map,
|
||||
cfi_qry_mode_off(base, map, cfi);
|
||||
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->bankwidth*8);
|
||||
map->bankwidth*8, cfi->mfr, cfi->id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/cfi.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
int __xipram cfi_qry_present(struct map_info *map, __u32 base,
|
||||
struct cfi_private *cfi)
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
static DEFINE_SPINLOCK(chip_drvs_lock);
|
||||
static LIST_HEAD(chip_drvs_list);
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/mtd.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_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/mtd.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 *);
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/mtd.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_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||
|
@ -1,7 +1,22 @@
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/mtd/compatmac.h> /* for min() in older kernels */
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/doc2000.h>
|
||||
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/doc2000.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
/* Where to look for the devices? */
|
||||
#ifndef CONFIG_MTD_DOCPROBE_ADDRESS
|
||||
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -639,8 +641,18 @@ static const struct spi_device_id m25p_ids[] = {
|
||||
{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, 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 */
|
||||
{ "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) },
|
||||
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) },
|
||||
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
|
||||
@ -680,6 +692,16 @@ static const struct spi_device_id m25p_ids[] = {
|
||||
{ "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 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) },
|
||||
{ "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) },
|
||||
{ "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) },
|
||||
@ -694,6 +716,7 @@ static const struct spi_device_id m25p_ids[] = {
|
||||
{ "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
|
||||
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, 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) },
|
||||
|
||||
/* Catalyst / On Semiconductor -- non-JEDEC */
|
||||
@ -723,7 +746,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
|
||||
if (tmp < 0) {
|
||||
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
|
||||
dev_name(&spi->dev), tmp);
|
||||
return NULL;
|
||||
return ERR_PTR(tmp);
|
||||
}
|
||||
jedec = id[0];
|
||||
jedec = jedec << 8;
|
||||
@ -731,14 +754,6 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
|
||||
jedec = jedec << 8;
|
||||
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];
|
||||
|
||||
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)
|
||||
return &m25p_ids[tmp];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
|
||||
@ -794,9 +809,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
|
||||
const struct spi_device_id *jid;
|
||||
|
||||
jid = jedec_probe(spi);
|
||||
if (!jid) {
|
||||
dev_info(&spi->dev, "non-JEDEC variant of %s\n",
|
||||
id->name);
|
||||
if (IS_ERR(jid)) {
|
||||
return PTR_ERR(jid);
|
||||
} else if (jid != id) {
|
||||
/*
|
||||
* JEDEC knows better, so overwrite platform ID. We
|
||||
@ -826,11 +840,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
|
||||
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
|
||||
*/
|
||||
|
||||
if (info->jedec_id >> 16 == 0x1f ||
|
||||
info->jedec_id >> 16 == 0x89 ||
|
||||
info->jedec_id >> 16 == 0xbf) {
|
||||
write_enable(flash);
|
||||
write_sr(flash, 0);
|
||||
|
@ -141,7 +141,7 @@ static int dataflash_waitready(struct spi_device *spi)
|
||||
*/
|
||||
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_transfer x = { .tx_dma = 0, };
|
||||
struct spi_message msg;
|
||||
@ -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,
|
||||
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_message msg;
|
||||
unsigned int addr;
|
||||
@ -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,
|
||||
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_transfer x[2] = { { .tx_dma = 0, }, };
|
||||
struct spi_message msg;
|
||||
@ -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,
|
||||
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;
|
||||
|
||||
/* 64 bytes, from 0..63 ... start at 64 on-chip */
|
||||
@ -532,7 +532,7 @@ static int dataflash_read_fact_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)
|
||||
{
|
||||
struct dataflash *priv = (struct dataflash *)mtd->priv;
|
||||
struct dataflash *priv = mtd->priv;
|
||||
int status;
|
||||
|
||||
/* 64 bytes, from 0..63 ... start at 0 on-chip */
|
||||
@ -553,7 +553,7 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
|
||||
const size_t l = 4 + 64;
|
||||
uint8_t *scratch;
|
||||
struct spi_transfer t;
|
||||
struct dataflash *priv = (struct dataflash *)mtd->priv;
|
||||
struct dataflash *priv = mtd->priv;
|
||||
int status;
|
||||
|
||||
if (len > 64)
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/mtdram.h>
|
||||
|
||||
|
@ -98,7 +98,6 @@
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/pmc551.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
static struct mtd_info *pmc551list;
|
||||
|
||||
|
@ -454,7 +454,7 @@ static int __init sst25l_probe(struct spi_device *spi)
|
||||
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",
|
||||
data->nr_parts, data->name);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
The initial developer of the original code is 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
|
||||
terms of the GNU General Public License version 2 (the "GPL"), in
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* 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:
|
||||
* (c) 1999 Machine Vision Holdings, Inc.
|
||||
* Author: David Woodhouse <dwmw2@infradead.org>
|
||||
* Copyright © 1999 Machine Vision Holdings, Inc.
|
||||
* Copyright © 1999 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
|
||||
|
@ -2,11 +2,11 @@
|
||||
* inftlmount.c -- INFTL mount code with extensive checks.
|
||||
*
|
||||
* 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:
|
||||
* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -34,7 +34,6 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nftl.h>
|
||||
#include <linux/mtd/inftl.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
/*
|
||||
* 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)
|
||||
numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum;
|
||||
for (i = 0; i < numchips; i++) {
|
||||
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++) {
|
||||
*chip = lpddr->chips[i];
|
||||
chip->start += j << lpddr->chipshift;
|
||||
@ -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 *contender;
|
||||
spin_lock(&shared->lock);
|
||||
mutex_lock(&shared->lock);
|
||||
contender = shared->writing;
|
||||
if (contender && contender != chip) {
|
||||
/*
|
||||
@ -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.
|
||||
*/
|
||||
ret = mutex_trylock(&contender->mutex);
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
if (!ret)
|
||||
goto retry;
|
||||
mutex_unlock(&chip->mutex);
|
||||
@ -245,7 +245,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
|
||||
mutex_unlock(&contender->mutex);
|
||||
return ret;
|
||||
}
|
||||
spin_lock(&shared->lock);
|
||||
mutex_lock(&shared->lock);
|
||||
|
||||
/* We should not own chip if it is already in FL_SYNCING
|
||||
* state. Put contender and retry. */
|
||||
@ -261,7 +261,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
|
||||
Must sleep in such a case. */
|
||||
if (mode == FL_ERASING && shared->erasing
|
||||
&& shared->erasing->oldstate == FL_ERASING) {
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
mutex_unlock(&chip->mutex);
|
||||
@ -275,7 +275,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
|
||||
shared->writing = chip;
|
||||
if (mode == FL_ERASING)
|
||||
shared->erasing = chip;
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
}
|
||||
|
||||
ret = chip_ready(map, chip, mode);
|
||||
@ -348,7 +348,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
|
||||
{
|
||||
if (chip->priv) {
|
||||
struct flchip_shared *shared = chip->priv;
|
||||
spin_lock(&shared->lock);
|
||||
mutex_lock(&shared->lock);
|
||||
if (shared->writing == chip && chip->oldstate == FL_READY) {
|
||||
/* We own the ability to write, but we're done */
|
||||
shared->writing = shared->erasing;
|
||||
@ -356,7 +356,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
|
||||
/* give back the ownership */
|
||||
struct flchip *loaner = shared->writing;
|
||||
mutex_lock(&loaner->mutex);
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
mutex_unlock(&chip->mutex);
|
||||
put_chip(map, loaner);
|
||||
mutex_lock(&chip->mutex);
|
||||
@ -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
|
||||
* we don't have ownership to resume anything.
|
||||
*/
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
wake_up(&chip->wq);
|
||||
return;
|
||||
}
|
||||
spin_unlock(&shared->lock);
|
||||
mutex_unlock(&shared->lock);
|
||||
}
|
||||
|
||||
switch (chip->oldstate) {
|
||||
|
@ -319,14 +319,6 @@ config MTD_CFI_FLAGADM
|
||||
Mapping for the Flaga digital module. If you don't have one, ignore
|
||||
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
|
||||
tristate "CFI Flash device mapped on Hitachi SolutionEngine"
|
||||
depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS
|
||||
|
@ -44,7 +44,6 @@ obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
|
||||
obj-$(CONFIG_MTD_EDB7312) += edb7312.o
|
||||
obj-$(CONFIG_MTD_IMPA7) += impa7.o
|
||||
obj-$(CONFIG_MTD_FORTUNET) += fortunet.o
|
||||
obj-$(CONFIG_MTD_REDWOOD) += redwood.o
|
||||
obj-$(CONFIG_MTD_UCLINUX) += uclinux.o
|
||||
obj-$(CONFIG_MTD_NETtel) += nettel.o
|
||||
obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
|
||||
|
@ -118,7 +118,7 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
|
||||
*dest++ = BYTE1(data);
|
||||
src += 2;
|
||||
len -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
*dest++ = BYTE0(flash_read16(src));
|
||||
@ -185,6 +185,8 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
|
||||
{
|
||||
struct flash_platform_data *plat = dev->dev.platform_data;
|
||||
struct ixp4xx_flash_info *info;
|
||||
const char *part_type = NULL;
|
||||
int nr_parts = 0;
|
||||
int err = -1;
|
||||
|
||||
if (!plat)
|
||||
@ -218,9 +220,9 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
|
||||
*/
|
||||
info->map.bankwidth = 2;
|
||||
info->map.name = dev_name(&dev->dev);
|
||||
info->map.read = ixp4xx_read16,
|
||||
info->map.write = ixp4xx_probe_write16,
|
||||
info->map.copy_from = ixp4xx_copy_from,
|
||||
info->map.read = ixp4xx_read16;
|
||||
info->map.write = ixp4xx_probe_write16;
|
||||
info->map.copy_from = ixp4xx_copy_from;
|
||||
|
||||
info->res = request_mem_region(dev->resource->start,
|
||||
resource_size(dev->resource),
|
||||
@ -248,11 +250,28 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
|
||||
info->mtd->owner = THIS_MODULE;
|
||||
|
||||
/* 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)
|
||||
printk(KERN_ERR "Could not parse partitions\n");
|
||||
}
|
||||
|
@ -106,12 +106,12 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||
|
||||
for (i = 0; i < dev->num_resources; i++) {
|
||||
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);
|
||||
|
||||
if (!devm_request_mem_region(&dev->dev,
|
||||
dev->resource[i].start,
|
||||
dev->resource[i].end - dev->resource[i].start + 1,
|
||||
resource_size(&dev->resource[i]),
|
||||
dev_name(&dev->dev))) {
|
||||
dev_err(&dev->dev, "Could not reserve memory region\n");
|
||||
err = -ENOMEM;
|
||||
@ -120,7 +120,7 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||
|
||||
info->map[i].name = dev_name(&dev->dev);
|
||||
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].set_vpp = physmap_data->set_vpp;
|
||||
info->map[i].pfow_base = physmap_data->pfow_base;
|
||||
@ -136,8 +136,12 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||
simple_map_init(&info->map[i]);
|
||||
|
||||
probe_type = rom_probe_types;
|
||||
for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
|
||||
info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
|
||||
if (physmap_data->probe_type == NULL) {
|
||||
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) {
|
||||
dev_err(&dev->dev, "map_probe failed\n");
|
||||
err = -ENXIO;
|
||||
|
@ -353,7 +353,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
|
||||
&info->parts, 0);
|
||||
if (err < 0) {
|
||||
of_free_probes(part_probe_types);
|
||||
return err;
|
||||
goto err_out;
|
||||
}
|
||||
of_free_probes(part_probe_types);
|
||||
|
||||
@ -361,14 +361,14 @@ static int __devinit of_flash_probe(struct of_device *dev,
|
||||
if (err == 0) {
|
||||
err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto err_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (err == 0) {
|
||||
err = parse_obsolete_partitions(dev, info, dp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (err > 0)
|
||||
|
@ -1,131 +0,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");
|
@ -1,7 +1,21 @@
|
||||
/*
|
||||
* (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,
|
||||
switch (cmd) {
|
||||
case BLKFLSBUF:
|
||||
ret = dev->tr->flush ? dev->tr->flush(dev) : 0;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
}
|
||||
@ -409,13 +424,14 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Stop new requests to arrive */
|
||||
del_gendisk(old->disk);
|
||||
|
||||
if (old->disk_attributes)
|
||||
sysfs_remove_group(&disk_to_dev(old->disk)->kobj,
|
||||
old->disk_attributes);
|
||||
|
||||
/* Stop new requests to arrive */
|
||||
del_gendisk(old->disk);
|
||||
|
||||
|
||||
/* Stop the thread */
|
||||
kthread_stop(old->thread);
|
||||
|
||||
|
@ -1,8 +1,23 @@
|
||||
/*
|
||||
* Direct MTD block device access
|
||||
*
|
||||
* (C) 2000-2003 Nicolas Pitre <nico@fluxnic.net>
|
||||
* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
|
||||
* Copyright © 1999-2010 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>
|
||||
|
@ -1,7 +1,22 @@
|
||||
/*
|
||||
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* 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>
|
||||
|
@ -1,5 +1,19 @@
|
||||
/*
|
||||
* 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 @@
|
||||
#include <linux/mount.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/mtd/map.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
@ -675,6 +689,20 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
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 */
|
||||
case MEMGETOOBSEL:
|
||||
{
|
||||
@ -950,9 +978,34 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
#ifdef CONFIG_MMU
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
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 -ENOSYS;
|
||||
#else
|
||||
return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
|
||||
|
@ -1,11 +1,25 @@
|
||||
/*
|
||||
* 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>
|
||||
*
|
||||
* 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>
|
||||
@ -540,10 +554,12 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
else
|
||||
size = len;
|
||||
|
||||
err = subdev->lock(subdev, ofs, size);
|
||||
|
||||
if (err)
|
||||
break;
|
||||
if (subdev->lock) {
|
||||
err = subdev->lock(subdev, ofs, size);
|
||||
if (err)
|
||||
break;
|
||||
} else
|
||||
err = -EOPNOTSUPP;
|
||||
|
||||
len -= size;
|
||||
if (len == 0)
|
||||
@ -578,10 +594,12 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
else
|
||||
size = len;
|
||||
|
||||
err = subdev->unlock(subdev, ofs, size);
|
||||
|
||||
if (err)
|
||||
break;
|
||||
if (subdev->unlock) {
|
||||
err = subdev->unlock(subdev, ofs, size);
|
||||
if (err)
|
||||
break;
|
||||
} else
|
||||
err = -EOPNOTSUPP;
|
||||
|
||||
len -= size;
|
||||
if (len == 0)
|
||||
|
@ -2,9 +2,23 @@
|
||||
* Core registration and callback routines for MTD
|
||||
* drivers and users.
|
||||
*
|
||||
* bdi bits are:
|
||||
* Copyright © 2006 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
* Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
* Copyright © 2006 Red Hat UK Limited
|
||||
*
|
||||
* 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>
|
||||
@ -17,7 +31,6 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/backing-dev.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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>
|
||||
*
|
||||
|
@ -1,12 +1,24 @@
|
||||
/*
|
||||
* 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>
|
||||
@ -17,7 +29,6 @@
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
/* Our partition linked list */
|
||||
static LIST_HEAD(mtd_partitions);
|
||||
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
@ -402,6 +421,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
|
||||
slave->mtd.lock = part_lock;
|
||||
if (master->unlock)
|
||||
slave->mtd.unlock = part_unlock;
|
||||
if (master->is_locked)
|
||||
slave->mtd.is_locked = part_is_locked;
|
||||
if (master->block_isbad)
|
||||
slave->mtd.block_isbad = part_block_isbad;
|
||||
if (master->block_markbad)
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* MTD-based superblock management
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Written by: David Howells <dhowells@redhat.com>
|
||||
* David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -37,7 +37,6 @@ config MTD_SM_COMMON
|
||||
|
||||
config MTD_NAND_MUSEUM_IDS
|
||||
bool "Enable chip ids for obsolete ancient NAND devices"
|
||||
depends on MTD_NAND
|
||||
default n
|
||||
help
|
||||
Enable this option only when your board has first generation
|
||||
@ -61,6 +60,7 @@ config MTD_NAND_DENALI
|
||||
config MTD_NAND_DENALI_SCRATCH_REG_ADDR
|
||||
hex "Denali NAND size scratch register address"
|
||||
default "0xFF108018"
|
||||
depends on MTD_NAND_DENALI
|
||||
help
|
||||
Some platforms place the NAND chip size in a scratch register
|
||||
because (some versions of) the driver aren't able to automatically
|
||||
@ -101,13 +101,13 @@ config MTD_NAND_AMS_DELTA
|
||||
|
||||
config MTD_NAND_OMAP2
|
||||
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
|
||||
Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
|
||||
|
||||
config MTD_NAND_OMAP_PREFETCH
|
||||
bool "GPMC prefetch support for NAND Flash device"
|
||||
depends on MTD_NAND && MTD_NAND_OMAP2
|
||||
depends on MTD_NAND_OMAP2
|
||||
default y
|
||||
help
|
||||
The NAND device can be accessed for Read/Write using GPMC PREFETCH engine
|
||||
@ -146,7 +146,7 @@ config MTD_NAND_AU1550
|
||||
|
||||
config MTD_NAND_BF5XX
|
||||
tristate "Blackfin on-chip NAND Flash Controller driver"
|
||||
depends on (BF54x || BF52x) && MTD_NAND
|
||||
depends on BF54x || BF52x
|
||||
help
|
||||
This enables the Blackfin on-chip NAND flash controller
|
||||
|
||||
@ -236,7 +236,7 @@ config MTD_NAND_S3C2410_CLKSTOP
|
||||
|
||||
config MTD_NAND_BCM_UMI
|
||||
tristate "NAND Flash support for BCM Reference Boards"
|
||||
depends on ARCH_BCMRING && MTD_NAND
|
||||
depends on ARCH_BCMRING
|
||||
help
|
||||
This enables the NAND flash controller on the BCM UMI block.
|
||||
|
||||
@ -395,7 +395,7 @@ endchoice
|
||||
|
||||
config MTD_NAND_PXA3xx
|
||||
tristate "Support for NAND flash devices on PXA3xx"
|
||||
depends on MTD_NAND && (PXA3xx || ARCH_MMP)
|
||||
depends on PXA3xx || ARCH_MMP
|
||||
help
|
||||
This enables the driver for the NAND flash device found on
|
||||
PXA3xx processors
|
||||
@ -409,18 +409,18 @@ config MTD_NAND_PXA3xx_BUILTIN
|
||||
|
||||
config MTD_NAND_CM_X270
|
||||
tristate "Support for NAND Flash on CM-X270 modules"
|
||||
depends on MTD_NAND && MACH_ARMCORE
|
||||
depends on MACH_ARMCORE
|
||||
|
||||
config MTD_NAND_PASEMI
|
||||
tristate "NAND support for PA Semi PWRficient"
|
||||
depends on MTD_NAND && PPC_PASEMI
|
||||
depends on PPC_PASEMI
|
||||
help
|
||||
Enables support for NAND Flash interface on PA Semi PWRficient
|
||||
based boards
|
||||
|
||||
config MTD_NAND_TMIO
|
||||
tristate "NAND Flash device on Toshiba Mobile IO Controller"
|
||||
depends on MTD_NAND && MFD_TMIO
|
||||
depends on MFD_TMIO
|
||||
help
|
||||
Support for NAND flash connected to a Toshiba Mobile IO
|
||||
Controller in some PDAs, including the Sharp SL6000x.
|
||||
@ -434,7 +434,6 @@ config MTD_NAND_NANDSIM
|
||||
|
||||
config MTD_NAND_PLATFORM
|
||||
tristate "Support for generic platform NAND driver"
|
||||
depends on MTD_NAND
|
||||
help
|
||||
This implements a generic NAND driver for on-SOC platform
|
||||
devices. You will need to provide platform-specific functions
|
||||
@ -442,14 +441,14 @@ config MTD_NAND_PLATFORM
|
||||
|
||||
config MTD_ALAUDA
|
||||
tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
|
||||
depends on MTD_NAND && USB
|
||||
depends on USB
|
||||
help
|
||||
These two (and possibly other) Alauda-based cardreaders for
|
||||
SmartMedia and xD allow raw flash access.
|
||||
|
||||
config MTD_NAND_ORION
|
||||
tristate "NAND Flash support for Marvell Orion SoC"
|
||||
depends on PLAT_ORION && MTD_NAND
|
||||
depends on PLAT_ORION
|
||||
help
|
||||
This enables the NAND flash controller on Orion machines.
|
||||
|
||||
@ -458,7 +457,7 @@ config MTD_NAND_ORION
|
||||
|
||||
config MTD_NAND_FSL_ELBC
|
||||
tristate "NAND support for Freescale eLBC controllers"
|
||||
depends on MTD_NAND && PPC_OF
|
||||
depends on PPC_OF
|
||||
help
|
||||
Various Freescale chips, including the 8313, include a NAND Flash
|
||||
Controller Module with built-in hardware ECC capabilities.
|
||||
@ -467,7 +466,7 @@ config MTD_NAND_FSL_ELBC
|
||||
|
||||
config MTD_NAND_FSL_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
|
||||
help
|
||||
Enables support for NAND Flash chips wired onto Freescale PowerPC
|
||||
@ -482,7 +481,7 @@ config MTD_NAND_MPC5121_NFC
|
||||
|
||||
config MTD_NAND_MXC
|
||||
tristate "MXC NAND support"
|
||||
depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3
|
||||
depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX51
|
||||
help
|
||||
This enables the driver for the NAND flash controller on the
|
||||
MXC processors.
|
||||
@ -495,7 +494,7 @@ config MTD_NAND_NOMADIK
|
||||
|
||||
config MTD_NAND_SH_FLCTL
|
||||
tristate "Support for NAND on Renesas SuperH FLCTL"
|
||||
depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE)
|
||||
depends on SUPERH || ARCH_SHMOBILE
|
||||
help
|
||||
Several Renesas SuperH CPU has FLCTL. This option enables support
|
||||
for NAND Flash using FLCTL.
|
||||
@ -515,7 +514,7 @@ config MTD_NAND_TXX9NDFMC
|
||||
|
||||
config MTD_NAND_SOCRATES
|
||||
tristate "Support for NAND on Socrates board"
|
||||
depends on MTD_NAND && SOCRATES
|
||||
depends on SOCRATES
|
||||
help
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
#ifdef CONFIG_MTD_CMDLINE_PARTS
|
||||
static const char *part_probes[] = { "cmdlinepart", NULL };
|
||||
#endif
|
||||
|
||||
|
@ -20,9 +20,6 @@
|
||||
* - DMA supported in ECC_HW
|
||||
* - 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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,
|
||||
|
||||
if (ctrl & NAND_CLE)
|
||||
bfin_write_NFC_CMD(cmd);
|
||||
else
|
||||
else if (ctrl & NAND_ALE)
|
||||
bfin_write_NFC_ADDR(cmd);
|
||||
SSYNC();
|
||||
}
|
||||
@ -218,9 +215,9 @@ static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd,
|
||||
*/
|
||||
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;
|
||||
else
|
||||
return 0;
|
||||
@ -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,
|
||||
u_char *read_ecc, u_char *calc_ecc)
|
||||
{
|
||||
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
|
||||
struct bf5xx_nand_platform *plat = info->platform;
|
||||
unsigned short page_size = (plat->page_size ? 512 : 256);
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
int ret;
|
||||
|
||||
ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
|
||||
|
||||
/* If page size is 512, correct second 256 bytes */
|
||||
if (page_size == 512) {
|
||||
/* If ecc size is 512, correct second 256 bytes */
|
||||
if (chip->ecc.size == 512) {
|
||||
dat += 256;
|
||||
read_ecc += 8;
|
||||
calc_ecc += 8;
|
||||
read_ecc += 3;
|
||||
calc_ecc += 3;
|
||||
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,
|
||||
const u_char *dat, u_char *ecc_code)
|
||||
{
|
||||
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
|
||||
struct bf5xx_nand_platform *plat = info->platform;
|
||||
u16 page_size = (plat->page_size ? 512 : 256);
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
u16 ecc0, ecc1;
|
||||
u32 code[2];
|
||||
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();
|
||||
ecc1 = bfin_read_NFC_ECC1();
|
||||
|
||||
@ -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]);
|
||||
|
||||
/* first 3 bytes in ecc_code for 256 page size */
|
||||
p = (u8 *) code;
|
||||
memcpy(ecc_code, p, 3);
|
||||
|
||||
/* second 4 bytes ECC code for 512 page size */
|
||||
if (page_size == 512) {
|
||||
/* second 3 bytes ECC code for 512 ecc size */
|
||||
if (chip->ecc.size == 512) {
|
||||
ecc0 = bfin_read_NFC_ECC2();
|
||||
ecc1 = bfin_read_NFC_ECC3();
|
||||
code[1] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11);
|
||||
@ -483,8 +476,7 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
|
||||
uint8_t *buf, int is_read)
|
||||
{
|
||||
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
|
||||
struct bf5xx_nand_platform *plat = info->platform;
|
||||
unsigned short page_size = (plat->page_size ? 512 : 256);
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
unsigned short val;
|
||||
|
||||
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,
|
||||
*/
|
||||
if (is_read)
|
||||
invalidate_dcache_range((unsigned int)buf,
|
||||
(unsigned int)(buf + page_size));
|
||||
(unsigned int)(buf + chip->ecc.size));
|
||||
else
|
||||
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
|
||||
@ -510,6 +502,8 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
|
||||
*/
|
||||
bfin_write_NFC_RST(ECC_RST);
|
||||
SSYNC();
|
||||
while (bfin_read_NFC_RST() & ECC_RST)
|
||||
cpu_relax();
|
||||
|
||||
disable_dma(CH_NFC);
|
||||
clear_dma_irqstat(CH_NFC);
|
||||
@ -520,13 +514,13 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
|
||||
|
||||
/* The DMAs have different size on BF52x and BF54x */
|
||||
#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);
|
||||
val = DI_EN | WDSIZE_16;
|
||||
#endif
|
||||
|
||||
#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);
|
||||
val = DI_EN | WDSIZE_32;
|
||||
#endif
|
||||
@ -548,12 +542,11 @@ static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
|
||||
uint8_t *buf, int len)
|
||||
{
|
||||
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
|
||||
struct bf5xx_nand_platform *plat = info->platform;
|
||||
unsigned short page_size = (plat->page_size ? 512 : 256);
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
|
||||
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);
|
||||
else
|
||||
bf5xx_nand_read_buf(mtd, buf, len);
|
||||
@ -563,17 +556,32 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
|
||||
const uint8_t *buf, int len)
|
||||
{
|
||||
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
|
||||
struct bf5xx_nand_platform *plat = info->platform;
|
||||
unsigned short page_size = (plat->page_size ? 512 : 256);
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
|
||||
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);
|
||||
else
|
||||
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
|
||||
*/
|
||||
@ -627,15 +635,14 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
|
||||
|
||||
/* setup NFC_CTL register */
|
||||
dev_info(info->device,
|
||||
"page_size=%d, data_width=%d, wr_dly=%d, rd_dly=%d\n",
|
||||
(plat->page_size ? 512 : 256),
|
||||
"data_width=%d, wr_dly=%d, rd_dly=%d\n",
|
||||
(plat->data_width ? 16 : 8),
|
||||
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->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);
|
||||
|
||||
bfin_write_NFC_CTL(val);
|
||||
@ -698,6 +705,33 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
|
||||
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
|
||||
*
|
||||
@ -783,27 +817,20 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
|
||||
chip->badblock_pattern = &bootrom_bbt;
|
||||
chip->ecc.layout = &bootrom_ecclayout;
|
||||
#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->write_buf = bf5xx_nand_dma_write_buf;
|
||||
chip->ecc.calculate = bf5xx_nand_calculate_ecc;
|
||||
chip->ecc.correct = bf5xx_nand_correct_data;
|
||||
chip->ecc.mode = NAND_ECC_HW;
|
||||
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 {
|
||||
chip->ecc.mode = NAND_ECC_SOFT;
|
||||
}
|
||||
|
||||
/* scan hardware nand chip and setup mtd info data struct */
|
||||
if (nand_scan(mtd, 1)) {
|
||||
if (bf5xx_nand_scan(mtd)) {
|
||||
err = -ENXIO;
|
||||
goto out_err_nand_scan;
|
||||
}
|
||||
|
@ -311,7 +311,9 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
|
||||
unsigned short ecc10[8];
|
||||
unsigned short *ecc16;
|
||||
u32 syndrome[4];
|
||||
u32 ecc_state;
|
||||
unsigned num_errors, corrected;
|
||||
unsigned long timeo = jiffies + msecs_to_jiffies(100);
|
||||
|
||||
/* All bytes 0xff? It's an erased page; ignore its ECC. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
@ -361,6 +363,21 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
|
||||
*/
|
||||
davinci_nand_writel(info, NANDFCR_OFFSET,
|
||||
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 (;;) {
|
||||
u32 fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
|
||||
#define DEVICE_RESET 0x0
|
||||
#define DEVICE_RESET__BANK0 0x0001
|
||||
@ -29,7 +29,7 @@
|
||||
#define TRANSFER_SPARE_REG__FLAG 0x0001
|
||||
|
||||
#define LOAD_WAIT_CNT 0x20
|
||||
#define LOAD_WAIT_CNT__VALUE 0xffff
|
||||
#define LOAD_WAIT_CNT__VALUE 0xffff
|
||||
|
||||
#define PROGRAM_WAIT_CNT 0x30
|
||||
#define PROGRAM_WAIT_CNT__VALUE 0xffff
|
||||
@ -83,7 +83,7 @@
|
||||
#define RE_2_WE 0x120
|
||||
#define RE_2_WE__VALUE 0x003f
|
||||
|
||||
#define ACC_CLKS 0x130
|
||||
#define ACC_CLKS 0x130
|
||||
#define ACC_CLKS__VALUE 0x000f
|
||||
|
||||
#define NUMBER_OF_PLANES 0x140
|
||||
@ -140,7 +140,7 @@
|
||||
#define DEVICES_CONNECTED 0x250
|
||||
#define DEVICES_CONNECTED__VALUE 0x0007
|
||||
|
||||
#define DIE_MASK 0x260
|
||||
#define DIE_MASK 0x260
|
||||
#define DIE_MASK__VALUE 0x00ff
|
||||
|
||||
#define FIRST_BLOCK_OF_NEXT_PLANE 0x270
|
||||
@ -152,7 +152,7 @@
|
||||
#define RE_2_RE 0x290
|
||||
#define RE_2_RE__VALUE 0x003f
|
||||
|
||||
#define MANUFACTURER_ID 0x300
|
||||
#define MANUFACTURER_ID 0x300
|
||||
#define MANUFACTURER_ID__VALUE 0x00ff
|
||||
|
||||
#define DEVICE_ID 0x310
|
||||
@ -173,13 +173,13 @@
|
||||
#define LOGICAL_PAGE_SPARE_SIZE 0x360
|
||||
#define LOGICAL_PAGE_SPARE_SIZE__VALUE 0xffff
|
||||
|
||||
#define REVISION 0x370
|
||||
#define REVISION 0x370
|
||||
#define REVISION__VALUE 0xffff
|
||||
|
||||
#define ONFI_DEVICE_FEATURES 0x380
|
||||
#define ONFI_DEVICE_FEATURES__VALUE 0x003f
|
||||
|
||||
#define ONFI_OPTIONAL_COMMANDS 0x390
|
||||
#define ONFI_OPTIONAL_COMMANDS 0x390
|
||||
#define ONFI_OPTIONAL_COMMANDS__VALUE 0x003f
|
||||
|
||||
#define ONFI_TIMING_MODE 0x3a0
|
||||
@ -201,12 +201,12 @@
|
||||
#define FEATURES 0x3f0
|
||||
#define FEATURES__N_BANKS 0x0003
|
||||
#define FEATURES__ECC_MAX_ERR 0x003c
|
||||
#define FEATURES__DMA 0x0040
|
||||
#define FEATURES__DMA 0x0040
|
||||
#define FEATURES__CMD_DMA 0x0080
|
||||
#define FEATURES__PARTITION 0x0100
|
||||
#define FEATURES__XDMA_SIDEBAND 0x0200
|
||||
#define FEATURES__GPREG 0x0400
|
||||
#define FEATURES__INDEX_ADDR 0x0800
|
||||
#define FEATURES__INDEX_ADDR 0x0800
|
||||
|
||||
#define TRANSFER_MODE 0x400
|
||||
#define TRANSFER_MODE__VALUE 0x0003
|
||||
@ -235,12 +235,12 @@
|
||||
#define INTR_EN0__DMA_CMD_COMP 0x0004
|
||||
#define INTR_EN0__TIME_OUT 0x0008
|
||||
#define INTR_EN0__PROGRAM_FAIL 0x0010
|
||||
#define INTR_EN0__ERASE_FAIL 0x0020
|
||||
#define INTR_EN0__ERASE_FAIL 0x0020
|
||||
#define INTR_EN0__LOAD_COMP 0x0040
|
||||
#define INTR_EN0__PROGRAM_COMP 0x0080
|
||||
#define INTR_EN0__ERASE_COMP 0x0100
|
||||
#define INTR_EN0__ERASE_COMP 0x0100
|
||||
#define INTR_EN0__PIPE_CPYBCK_CMD_COMP 0x0200
|
||||
#define INTR_EN0__LOCKED_BLK 0x0400
|
||||
#define INTR_EN0__LOCKED_BLK 0x0400
|
||||
#define INTR_EN0__UNSUP_CMD 0x0800
|
||||
#define INTR_EN0__INT_ACT 0x1000
|
||||
#define INTR_EN0__RST_COMP 0x2000
|
||||
@ -253,7 +253,7 @@
|
||||
#define ERR_PAGE_ADDR0 0x440
|
||||
#define ERR_PAGE_ADDR0__VALUE 0xffff
|
||||
|
||||
#define ERR_BLOCK_ADDR0 0x450
|
||||
#define ERR_BLOCK_ADDR0 0x450
|
||||
#define ERR_BLOCK_ADDR0__VALUE 0xffff
|
||||
|
||||
#define INTR_STATUS1 0x460
|
||||
@ -280,12 +280,12 @@
|
||||
#define INTR_EN1__DMA_CMD_COMP 0x0004
|
||||
#define INTR_EN1__TIME_OUT 0x0008
|
||||
#define INTR_EN1__PROGRAM_FAIL 0x0010
|
||||
#define INTR_EN1__ERASE_FAIL 0x0020
|
||||
#define INTR_EN1__ERASE_FAIL 0x0020
|
||||
#define INTR_EN1__LOAD_COMP 0x0040
|
||||
#define INTR_EN1__PROGRAM_COMP 0x0080
|
||||
#define INTR_EN1__ERASE_COMP 0x0100
|
||||
#define INTR_EN1__ERASE_COMP 0x0100
|
||||
#define INTR_EN1__PIPE_CPYBCK_CMD_COMP 0x0200
|
||||
#define INTR_EN1__LOCKED_BLK 0x0400
|
||||
#define INTR_EN1__LOCKED_BLK 0x0400
|
||||
#define INTR_EN1__UNSUP_CMD 0x0800
|
||||
#define INTR_EN1__INT_ACT 0x1000
|
||||
#define INTR_EN1__RST_COMP 0x2000
|
||||
@ -298,7 +298,7 @@
|
||||
#define ERR_PAGE_ADDR1 0x490
|
||||
#define ERR_PAGE_ADDR1__VALUE 0xffff
|
||||
|
||||
#define ERR_BLOCK_ADDR1 0x4a0
|
||||
#define ERR_BLOCK_ADDR1 0x4a0
|
||||
#define ERR_BLOCK_ADDR1__VALUE 0xffff
|
||||
|
||||
#define INTR_STATUS2 0x4b0
|
||||
@ -325,12 +325,12 @@
|
||||
#define INTR_EN2__DMA_CMD_COMP 0x0004
|
||||
#define INTR_EN2__TIME_OUT 0x0008
|
||||
#define INTR_EN2__PROGRAM_FAIL 0x0010
|
||||
#define INTR_EN2__ERASE_FAIL 0x0020
|
||||
#define INTR_EN2__ERASE_FAIL 0x0020
|
||||
#define INTR_EN2__LOAD_COMP 0x0040
|
||||
#define INTR_EN2__PROGRAM_COMP 0x0080
|
||||
#define INTR_EN2__ERASE_COMP 0x0100
|
||||
#define INTR_EN2__ERASE_COMP 0x0100
|
||||
#define INTR_EN2__PIPE_CPYBCK_CMD_COMP 0x0200
|
||||
#define INTR_EN2__LOCKED_BLK 0x0400
|
||||
#define INTR_EN2__LOCKED_BLK 0x0400
|
||||
#define INTR_EN2__UNSUP_CMD 0x0800
|
||||
#define INTR_EN2__INT_ACT 0x1000
|
||||
#define INTR_EN2__RST_COMP 0x2000
|
||||
@ -343,7 +343,7 @@
|
||||
#define ERR_PAGE_ADDR2 0x4e0
|
||||
#define ERR_PAGE_ADDR2__VALUE 0xffff
|
||||
|
||||
#define ERR_BLOCK_ADDR2 0x4f0
|
||||
#define ERR_BLOCK_ADDR2 0x4f0
|
||||
#define ERR_BLOCK_ADDR2__VALUE 0xffff
|
||||
|
||||
#define INTR_STATUS3 0x500
|
||||
@ -370,12 +370,12 @@
|
||||
#define INTR_EN3__DMA_CMD_COMP 0x0004
|
||||
#define INTR_EN3__TIME_OUT 0x0008
|
||||
#define INTR_EN3__PROGRAM_FAIL 0x0010
|
||||
#define INTR_EN3__ERASE_FAIL 0x0020
|
||||
#define INTR_EN3__ERASE_FAIL 0x0020
|
||||
#define INTR_EN3__LOAD_COMP 0x0040
|
||||
#define INTR_EN3__PROGRAM_COMP 0x0080
|
||||
#define INTR_EN3__ERASE_COMP 0x0100
|
||||
#define INTR_EN3__ERASE_COMP 0x0100
|
||||
#define INTR_EN3__PIPE_CPYBCK_CMD_COMP 0x0200
|
||||
#define INTR_EN3__LOCKED_BLK 0x0400
|
||||
#define INTR_EN3__LOCKED_BLK 0x0400
|
||||
#define INTR_EN3__UNSUP_CMD 0x0800
|
||||
#define INTR_EN3__INT_ACT 0x1000
|
||||
#define INTR_EN3__RST_COMP 0x2000
|
||||
@ -388,7 +388,7 @@
|
||||
#define ERR_PAGE_ADDR3 0x530
|
||||
#define ERR_PAGE_ADDR3__VALUE 0xffff
|
||||
|
||||
#define ERR_BLOCK_ADDR3 0x540
|
||||
#define ERR_BLOCK_ADDR3 0x540
|
||||
#define ERR_BLOCK_ADDR3__VALUE 0xffff
|
||||
|
||||
#define DATA_INTR 0x550
|
||||
@ -412,9 +412,9 @@
|
||||
#define GPREG_3__VALUE 0xffff
|
||||
|
||||
#define ECC_THRESHOLD 0x600
|
||||
#define ECC_THRESHOLD__VALUE 0x03ff
|
||||
#define ECC_THRESHOLD__VALUE 0x03ff
|
||||
|
||||
#define ECC_ERROR_BLOCK_ADDRESS 0x610
|
||||
#define ECC_ERROR_BLOCK_ADDRESS 0x610
|
||||
#define ECC_ERROR_BLOCK_ADDRESS__VALUE 0xffff
|
||||
|
||||
#define ECC_ERROR_PAGE_ADDRESS 0x620
|
||||
@ -466,7 +466,7 @@
|
||||
#define CHNL_ACTIVE__CHANNEL3 0x0008
|
||||
|
||||
#define ACTIVE_SRC_ID 0x800
|
||||
#define ACTIVE_SRC_ID__VALUE 0x00ff
|
||||
#define ACTIVE_SRC_ID__VALUE 0x00ff
|
||||
|
||||
#define PTN_INTR 0x810
|
||||
#define PTN_INTR__CONFIG_ERROR 0x0001
|
||||
@ -485,7 +485,7 @@
|
||||
#define PTN_INTR_EN__REG_ACCESS_ERROR 0x0020
|
||||
|
||||
#define PERM_SRC_ID_0 0x830
|
||||
#define PERM_SRC_ID_0__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_0__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_0__DIRECT_ACCESS_ACTIVE 0x0800
|
||||
#define PERM_SRC_ID_0__WRITE_ACTIVE 0x2000
|
||||
#define PERM_SRC_ID_0__READ_ACTIVE 0x4000
|
||||
@ -502,7 +502,7 @@
|
||||
#define MIN_MAX_BANK_0__MAX_VALUE 0x000c
|
||||
|
||||
#define PERM_SRC_ID_1 0x870
|
||||
#define PERM_SRC_ID_1__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_1__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_1__DIRECT_ACCESS_ACTIVE 0x0800
|
||||
#define PERM_SRC_ID_1__WRITE_ACTIVE 0x2000
|
||||
#define PERM_SRC_ID_1__READ_ACTIVE 0x4000
|
||||
@ -519,7 +519,7 @@
|
||||
#define MIN_MAX_BANK_1__MAX_VALUE 0x000c
|
||||
|
||||
#define PERM_SRC_ID_2 0x8b0
|
||||
#define PERM_SRC_ID_2__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_2__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_2__DIRECT_ACCESS_ACTIVE 0x0800
|
||||
#define PERM_SRC_ID_2__WRITE_ACTIVE 0x2000
|
||||
#define PERM_SRC_ID_2__READ_ACTIVE 0x4000
|
||||
@ -536,7 +536,7 @@
|
||||
#define MIN_MAX_BANK_2__MAX_VALUE 0x000c
|
||||
|
||||
#define PERM_SRC_ID_3 0x8f0
|
||||
#define PERM_SRC_ID_3__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_3__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_3__DIRECT_ACCESS_ACTIVE 0x0800
|
||||
#define PERM_SRC_ID_3__WRITE_ACTIVE 0x2000
|
||||
#define PERM_SRC_ID_3__READ_ACTIVE 0x4000
|
||||
@ -553,7 +553,7 @@
|
||||
#define MIN_MAX_BANK_3__MAX_VALUE 0x000c
|
||||
|
||||
#define PERM_SRC_ID_4 0x930
|
||||
#define PERM_SRC_ID_4__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_4__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_4__DIRECT_ACCESS_ACTIVE 0x0800
|
||||
#define PERM_SRC_ID_4__WRITE_ACTIVE 0x2000
|
||||
#define PERM_SRC_ID_4__READ_ACTIVE 0x4000
|
||||
@ -570,7 +570,7 @@
|
||||
#define MIN_MAX_BANK_4__MAX_VALUE 0x000c
|
||||
|
||||
#define PERM_SRC_ID_5 0x970
|
||||
#define PERM_SRC_ID_5__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_5__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_5__DIRECT_ACCESS_ACTIVE 0x0800
|
||||
#define PERM_SRC_ID_5__WRITE_ACTIVE 0x2000
|
||||
#define PERM_SRC_ID_5__READ_ACTIVE 0x4000
|
||||
@ -587,7 +587,7 @@
|
||||
#define MIN_MAX_BANK_5__MAX_VALUE 0x000c
|
||||
|
||||
#define PERM_SRC_ID_6 0x9b0
|
||||
#define PERM_SRC_ID_6__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_6__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_6__DIRECT_ACCESS_ACTIVE 0x0800
|
||||
#define PERM_SRC_ID_6__WRITE_ACTIVE 0x2000
|
||||
#define PERM_SRC_ID_6__READ_ACTIVE 0x4000
|
||||
@ -604,7 +604,7 @@
|
||||
#define MIN_MAX_BANK_6__MAX_VALUE 0x000c
|
||||
|
||||
#define PERM_SRC_ID_7 0x9f0
|
||||
#define PERM_SRC_ID_7__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_7__SRCID 0x00ff
|
||||
#define PERM_SRC_ID_7__DIRECT_ACCESS_ACTIVE 0x0800
|
||||
#define PERM_SRC_ID_7__WRITE_ACTIVE 0x2000
|
||||
#define PERM_SRC_ID_7__READ_ACTIVE 0x4000
|
||||
@ -620,47 +620,6 @@
|
||||
#define MIN_MAX_BANK_7__MIN_VALUE 0x0003
|
||||
#define MIN_MAX_BANK_7__MAX_VALUE 0x000c
|
||||
|
||||
/* flash.h */
|
||||
struct device_info_tag {
|
||||
uint16_t wDeviceMaker;
|
||||
uint16_t wDeviceID;
|
||||
uint8_t bDeviceParam0;
|
||||
uint8_t bDeviceParam1;
|
||||
uint8_t bDeviceParam2;
|
||||
uint32_t wDeviceType;
|
||||
uint32_t wSpectraStartBlock;
|
||||
uint32_t wSpectraEndBlock;
|
||||
uint32_t wTotalBlocks;
|
||||
uint16_t wPagesPerBlock;
|
||||
uint16_t wPageSize;
|
||||
uint16_t wPageDataSize;
|
||||
uint16_t wPageSpareSize;
|
||||
uint16_t wNumPageSpareFlag;
|
||||
uint16_t wECCBytesPerSector;
|
||||
uint32_t wBlockSize;
|
||||
uint32_t wBlockDataSize;
|
||||
uint32_t wDataBlockNum;
|
||||
uint8_t bPlaneNum;
|
||||
uint16_t wDeviceMainAreaSize;
|
||||
uint16_t wDeviceSpareAreaSize;
|
||||
uint16_t wDevicesConnected;
|
||||
uint16_t wDeviceWidth;
|
||||
uint16_t wHWRevision;
|
||||
uint16_t wHWFeatures;
|
||||
|
||||
uint16_t wONFIDevFeatures;
|
||||
uint16_t wONFIOptCommands;
|
||||
uint16_t wONFITimingMode;
|
||||
uint16_t wONFIPgmCacheTimingMode;
|
||||
|
||||
uint16_t MLCDevice;
|
||||
uint16_t wSpareSkipBytes;
|
||||
|
||||
uint8_t nBitsInPageNumber;
|
||||
uint8_t nBitsInPageDataSize;
|
||||
uint8_t nBitsInBlockDataSize;
|
||||
};
|
||||
|
||||
/* ffsdefs.h */
|
||||
#define CLEAR 0 /*use this to clear a field instead of "fail"*/
|
||||
#define SET 1 /*use this to set a field instead of "pass"*/
|
||||
@ -684,11 +643,11 @@ struct device_info_tag {
|
||||
#define NAND_DBG_TRACE 3
|
||||
|
||||
#ifdef VERBOSE
|
||||
#define nand_dbg_print(level, args...) \
|
||||
do { \
|
||||
if (level <= nand_debug_level) \
|
||||
printk(KERN_ALERT args); \
|
||||
} while (0)
|
||||
#define nand_dbg_print(level, args...) \
|
||||
do { \
|
||||
if (level <= nand_debug_level) \
|
||||
printk(KERN_ALERT args); \
|
||||
} while (0)
|
||||
#else
|
||||
#define nand_dbg_print(level, args...)
|
||||
#endif
|
||||
@ -772,10 +731,9 @@ struct device_info_tag {
|
||||
#define ECC_SECTOR_SIZE 512
|
||||
#define LLD_MAX_FLASH_BANKS 4
|
||||
|
||||
#define DENALI_BUF_SIZE NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE
|
||||
#define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE)
|
||||
|
||||
struct nand_buf
|
||||
{
|
||||
struct nand_buf {
|
||||
int head;
|
||||
int tail;
|
||||
uint8_t buf[DENALI_BUF_SIZE];
|
||||
@ -788,7 +746,6 @@ struct nand_buf
|
||||
struct denali_nand_info {
|
||||
struct mtd_info mtd;
|
||||
struct nand_chip nand;
|
||||
struct device_info_tag dev_info;
|
||||
int flash_bank; /* currently selected chip */
|
||||
int status;
|
||||
int platform;
|
||||
@ -806,11 +763,12 @@ struct denali_nand_info {
|
||||
uint32_t irq_status;
|
||||
int irq_debug_array[32];
|
||||
int idx;
|
||||
|
||||
uint32_t devnum; /* represent how many nands connected */
|
||||
uint32_t fwblks; /* represent how many blocks FW used */
|
||||
uint32_t totalblks;
|
||||
uint32_t blksperchip;
|
||||
uint32_t bbtskipbytes;
|
||||
};
|
||||
|
||||
static uint16_t NAND_Flash_Reset(struct denali_nand_info *denali);
|
||||
static uint16_t NAND_Read_Device_ID(struct denali_nand_info *denali);
|
||||
static void NAND_LLD_Enable_Disable_Interrupts(struct denali_nand_info *denali, uint16_t INT_ENABLE);
|
||||
|
||||
#endif /*_LLD_NAND_*/
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/doc2000.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/mtd/partitions.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)
|
||||
uint8_t parity;
|
||||
uint16_t ds[4], s[5], tmp, errval[8], syn[4];
|
||||
|
||||
memset(syn, 0, sizeof(syn));
|
||||
/* Convert the ecc bytes into words */
|
||||
ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8);
|
||||
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)
|
||||
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++) {
|
||||
if (syn[i])
|
||||
if (s[i])
|
||||
syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
|
||||
}
|
||||
/* Call the decoder library */
|
||||
|
@ -39,60 +39,96 @@
|
||||
|
||||
#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35())
|
||||
#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
|
||||
#define nfc_is_v3_2() cpu_is_mx51()
|
||||
#define nfc_is_v3() nfc_is_v3_2()
|
||||
|
||||
/* Addresses for NFC registers */
|
||||
#define NFC_BUF_SIZE 0xE00
|
||||
#define NFC_BUF_ADDR 0xE04
|
||||
#define NFC_FLASH_ADDR 0xE06
|
||||
#define NFC_FLASH_CMD 0xE08
|
||||
#define NFC_CONFIG 0xE0A
|
||||
#define NFC_ECC_STATUS_RESULT 0xE0C
|
||||
#define NFC_RSLTMAIN_AREA 0xE0E
|
||||
#define NFC_RSLTSPARE_AREA 0xE10
|
||||
#define NFC_WRPROT 0xE12
|
||||
#define NFC_V1_UNLOCKSTART_BLKADDR 0xe14
|
||||
#define NFC_V1_UNLOCKEND_BLKADDR 0xe16
|
||||
#define NFC_V21_UNLOCKSTART_BLKADDR 0xe20
|
||||
#define NFC_V21_UNLOCKEND_BLKADDR 0xe22
|
||||
#define NFC_NF_WRPRST 0xE18
|
||||
#define NFC_CONFIG1 0xE1A
|
||||
#define NFC_CONFIG2 0xE1C
|
||||
#define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
|
||||
#define NFC_V1_V2_BUF_ADDR (host->regs + 0x04)
|
||||
#define NFC_V1_V2_FLASH_ADDR (host->regs + 0x06)
|
||||
#define NFC_V1_V2_FLASH_CMD (host->regs + 0x08)
|
||||
#define NFC_V1_V2_CONFIG (host->regs + 0x0a)
|
||||
#define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c)
|
||||
#define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e)
|
||||
#define NFC_V1_V2_RSLTSPARE_AREA (host->regs + 0x10)
|
||||
#define NFC_V1_V2_WRPROT (host->regs + 0x12)
|
||||
#define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)
|
||||
#define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
|
||||
#define NFC_V21_UNLOCKSTART_BLKADDR (host->regs + 0x20)
|
||||
#define NFC_V21_UNLOCKEND_BLKADDR (host->regs + 0x22)
|
||||
#define NFC_V1_V2_NF_WRPRST (host->regs + 0x18)
|
||||
#define NFC_V1_V2_CONFIG1 (host->regs + 0x1a)
|
||||
#define NFC_V1_V2_CONFIG2 (host->regs + 0x1c)
|
||||
|
||||
/* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register
|
||||
* for Command operation */
|
||||
#define NFC_CMD 0x1
|
||||
#define NFC_V2_CONFIG1_ECC_MODE_4 (1 << 0)
|
||||
#define NFC_V1_V2_CONFIG1_SP_EN (1 << 2)
|
||||
#define NFC_V1_V2_CONFIG1_ECC_EN (1 << 3)
|
||||
#define NFC_V1_V2_CONFIG1_INT_MSK (1 << 4)
|
||||
#define NFC_V1_V2_CONFIG1_BIG (1 << 5)
|
||||
#define NFC_V1_V2_CONFIG1_RST (1 << 6)
|
||||
#define NFC_V1_V2_CONFIG1_CE (1 << 7)
|
||||
#define NFC_V1_V2_CONFIG1_ONE_CYCLE (1 << 8)
|
||||
|
||||
/* Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register
|
||||
* for Address operation */
|
||||
#define NFC_ADDR 0x2
|
||||
#define NFC_V1_V2_CONFIG2_INT (1 << 15)
|
||||
|
||||
/* Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register
|
||||
* for Input operation */
|
||||
#define NFC_INPUT 0x4
|
||||
/*
|
||||
* Operation modes for the NFC. Valid for v1, v2 and v3
|
||||
* type controllers.
|
||||
*/
|
||||
#define NFC_CMD (1 << 0)
|
||||
#define NFC_ADDR (1 << 1)
|
||||
#define NFC_INPUT (1 << 2)
|
||||
#define NFC_OUTPUT (1 << 3)
|
||||
#define NFC_ID (1 << 4)
|
||||
#define NFC_STATUS (1 << 5)
|
||||
|
||||
/* Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register
|
||||
* for Data Output operation */
|
||||
#define NFC_OUTPUT 0x8
|
||||
#define NFC_V3_FLASH_CMD (host->regs_axi + 0x00)
|
||||
#define NFC_V3_FLASH_ADDR0 (host->regs_axi + 0x04)
|
||||
|
||||
/* Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register
|
||||
* for Read ID operation */
|
||||
#define NFC_ID 0x10
|
||||
#define NFC_V3_CONFIG1 (host->regs_axi + 0x34)
|
||||
#define NFC_V3_CONFIG1_SP_EN (1 << 0)
|
||||
#define NFC_V3_CONFIG1_RBA(x) (((x) & 0x7 ) << 4)
|
||||
|
||||
/* Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register
|
||||
* for Read Status operation */
|
||||
#define NFC_STATUS 0x20
|
||||
#define NFC_V3_ECC_STATUS_RESULT (host->regs_axi + 0x38)
|
||||
|
||||
/* Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read
|
||||
* Status operation */
|
||||
#define NFC_INT 0x8000
|
||||
#define NFC_V3_LAUNCH (host->regs_axi + 0x40)
|
||||
|
||||
#define NFC_SP_EN (1 << 2)
|
||||
#define NFC_ECC_EN (1 << 3)
|
||||
#define NFC_INT_MSK (1 << 4)
|
||||
#define NFC_BIG (1 << 5)
|
||||
#define NFC_RST (1 << 6)
|
||||
#define NFC_CE (1 << 7)
|
||||
#define NFC_ONE_CYCLE (1 << 8)
|
||||
#define NFC_V3_WRPROT (host->regs_ip + 0x0)
|
||||
#define NFC_V3_WRPROT_LOCK_TIGHT (1 << 0)
|
||||
#define NFC_V3_WRPROT_LOCK (1 << 1)
|
||||
#define NFC_V3_WRPROT_UNLOCK (1 << 2)
|
||||
#define NFC_V3_WRPROT_BLS_UNLOCK (2 << 6)
|
||||
|
||||
#define NFC_V3_WRPROT_UNLOCK_BLK_ADD0 (host->regs_ip + 0x04)
|
||||
|
||||
#define NFC_V3_CONFIG2 (host->regs_ip + 0x24)
|
||||
#define NFC_V3_CONFIG2_PS_512 (0 << 0)
|
||||
#define NFC_V3_CONFIG2_PS_2048 (1 << 0)
|
||||
#define NFC_V3_CONFIG2_PS_4096 (2 << 0)
|
||||
#define NFC_V3_CONFIG2_ONE_CYCLE (1 << 2)
|
||||
#define NFC_V3_CONFIG2_ECC_EN (1 << 3)
|
||||
#define NFC_V3_CONFIG2_2CMD_PHASES (1 << 4)
|
||||
#define NFC_V3_CONFIG2_NUM_ADDR_PHASE0 (1 << 5)
|
||||
#define NFC_V3_CONFIG2_ECC_MODE_8 (1 << 6)
|
||||
#define NFC_V3_CONFIG2_PPB(x) (((x) & 0x3) << 7)
|
||||
#define NFC_V3_CONFIG2_NUM_ADDR_PHASE1(x) (((x) & 0x3) << 12)
|
||||
#define NFC_V3_CONFIG2_INT_MSK (1 << 15)
|
||||
#define NFC_V3_CONFIG2_ST_CMD(x) (((x) & 0xff) << 24)
|
||||
#define NFC_V3_CONFIG2_SPAS(x) (((x) & 0xff) << 16)
|
||||
|
||||
#define NFC_V3_CONFIG3 (host->regs_ip + 0x28)
|
||||
#define NFC_V3_CONFIG3_ADD_OP(x) (((x) & 0x3) << 0)
|
||||
#define NFC_V3_CONFIG3_FW8 (1 << 3)
|
||||
#define NFC_V3_CONFIG3_SBB(x) (((x) & 0x7) << 8)
|
||||
#define NFC_V3_CONFIG3_NUM_OF_DEVICES(x) (((x) & 0x7) << 12)
|
||||
#define NFC_V3_CONFIG3_RBB_MODE (1 << 15)
|
||||
#define NFC_V3_CONFIG3_NO_SDMA (1 << 20)
|
||||
|
||||
#define NFC_V3_IPC (host->regs_ip + 0x2C)
|
||||
#define NFC_V3_IPC_CREQ (1 << 0)
|
||||
#define NFC_V3_IPC_INT (1 << 31)
|
||||
|
||||
#define NFC_V3_DELAY_LINE (host->regs_ip + 0x34)
|
||||
|
||||
struct mxc_nand_host {
|
||||
struct mtd_info mtd;
|
||||
@ -102,20 +138,30 @@ struct mxc_nand_host {
|
||||
|
||||
void *spare0;
|
||||
void *main_area0;
|
||||
void *main_area1;
|
||||
|
||||
void __iomem *base;
|
||||
void __iomem *regs;
|
||||
void __iomem *regs_axi;
|
||||
void __iomem *regs_ip;
|
||||
int status_request;
|
||||
struct clk *clk;
|
||||
int clk_act;
|
||||
int irq;
|
||||
int eccsize;
|
||||
|
||||
wait_queue_head_t irq_waitq;
|
||||
|
||||
uint8_t *data_buf;
|
||||
unsigned int buf_start;
|
||||
int spare_len;
|
||||
|
||||
void (*preset)(struct mtd_info *);
|
||||
void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
|
||||
void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
|
||||
void (*send_page)(struct mtd_info *, unsigned int);
|
||||
void (*send_read_id)(struct mxc_nand_host *);
|
||||
uint16_t (*get_dev_status)(struct mxc_nand_host *);
|
||||
int (*check_int)(struct mxc_nand_host *);
|
||||
};
|
||||
|
||||
/* OOB placement block for use with hardware ecc generation */
|
||||
@ -175,34 +221,52 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int check_int_v3(struct mxc_nand_host *host)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = readl(NFC_V3_IPC);
|
||||
if (!(tmp & NFC_V3_IPC_INT))
|
||||
return 0;
|
||||
|
||||
tmp &= ~NFC_V3_IPC_INT;
|
||||
writel(tmp, NFC_V3_IPC);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int check_int_v1_v2(struct mxc_nand_host *host)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = readw(NFC_V1_V2_CONFIG2);
|
||||
if (!(tmp & NFC_V1_V2_CONFIG2_INT))
|
||||
return 0;
|
||||
|
||||
writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This function polls the NANDFC to wait for the basic operation to
|
||||
* complete by checking the INT bit of config2 register.
|
||||
*/
|
||||
static void wait_op_done(struct mxc_nand_host *host, int useirq)
|
||||
{
|
||||
uint16_t tmp;
|
||||
int max_retries = 8000;
|
||||
|
||||
if (useirq) {
|
||||
if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) {
|
||||
if (!host->check_int(host)) {
|
||||
|
||||
enable_irq(host->irq);
|
||||
|
||||
wait_event(host->irq_waitq,
|
||||
readw(host->regs + NFC_CONFIG2) & NFC_INT);
|
||||
|
||||
tmp = readw(host->regs + NFC_CONFIG2);
|
||||
tmp &= ~NFC_INT;
|
||||
writew(tmp, host->regs + NFC_CONFIG2);
|
||||
wait_event(host->irq_waitq, host->check_int(host));
|
||||
}
|
||||
} else {
|
||||
while (max_retries-- > 0) {
|
||||
if (readw(host->regs + NFC_CONFIG2) & NFC_INT) {
|
||||
tmp = readw(host->regs + NFC_CONFIG2);
|
||||
tmp &= ~NFC_INT;
|
||||
writew(tmp, host->regs + NFC_CONFIG2);
|
||||
if (host->check_int(host))
|
||||
break;
|
||||
}
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
if (max_retries < 0)
|
||||
@ -211,21 +275,33 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
|
||||
}
|
||||
}
|
||||
|
||||
static void send_cmd_v3(struct mxc_nand_host *host, uint16_t cmd, int useirq)
|
||||
{
|
||||
/* fill command */
|
||||
writel(cmd, NFC_V3_FLASH_CMD);
|
||||
|
||||
/* send out command */
|
||||
writel(NFC_CMD, NFC_V3_LAUNCH);
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(host, useirq);
|
||||
}
|
||||
|
||||
/* This function issues the specified command to the NAND device and
|
||||
* waits for completion. */
|
||||
static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
|
||||
static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
|
||||
{
|
||||
DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq);
|
||||
|
||||
writew(cmd, host->regs + NFC_FLASH_CMD);
|
||||
writew(NFC_CMD, host->regs + NFC_CONFIG2);
|
||||
writew(cmd, NFC_V1_V2_FLASH_CMD);
|
||||
writew(NFC_CMD, NFC_V1_V2_CONFIG2);
|
||||
|
||||
if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) {
|
||||
int max_retries = 100;
|
||||
/* Reset completion is indicated by NFC_CONFIG2 */
|
||||
/* being set to 0 */
|
||||
while (max_retries-- > 0) {
|
||||
if (readw(host->regs + NFC_CONFIG2) == 0) {
|
||||
if (readw(NFC_V1_V2_CONFIG2) == 0) {
|
||||
break;
|
||||
}
|
||||
udelay(1);
|
||||
@ -239,21 +315,48 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
|
||||
}
|
||||
}
|
||||
|
||||
static void send_addr_v3(struct mxc_nand_host *host, uint16_t addr, int islast)
|
||||
{
|
||||
/* fill address */
|
||||
writel(addr, NFC_V3_FLASH_ADDR0);
|
||||
|
||||
/* send out address */
|
||||
writel(NFC_ADDR, NFC_V3_LAUNCH);
|
||||
|
||||
wait_op_done(host, 0);
|
||||
}
|
||||
|
||||
/* This function sends an address (or partial address) to the
|
||||
* NAND device. The address is used to select the source/destination for
|
||||
* a NAND command. */
|
||||
static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast)
|
||||
static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islast)
|
||||
{
|
||||
DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
|
||||
|
||||
writew(addr, host->regs + NFC_FLASH_ADDR);
|
||||
writew(NFC_ADDR, host->regs + NFC_CONFIG2);
|
||||
writew(addr, NFC_V1_V2_FLASH_ADDR);
|
||||
writew(NFC_ADDR, NFC_V1_V2_CONFIG2);
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(host, islast);
|
||||
}
|
||||
|
||||
static void send_page(struct mtd_info *mtd, unsigned int ops)
|
||||
static void send_page_v3(struct mtd_info *mtd, unsigned int ops)
|
||||
{
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
struct mxc_nand_host *host = nand_chip->priv;
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = readl(NFC_V3_CONFIG1);
|
||||
tmp &= ~(7 << 4);
|
||||
writel(tmp, NFC_V3_CONFIG1);
|
||||
|
||||
/* transfer data from NFC ram to nand */
|
||||
writel(ops, NFC_V3_LAUNCH);
|
||||
|
||||
wait_op_done(host, false);
|
||||
}
|
||||
|
||||
static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
|
||||
{
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
struct mxc_nand_host *host = nand_chip->priv;
|
||||
@ -267,24 +370,34 @@ static void send_page(struct mtd_info *mtd, unsigned int ops)
|
||||
for (i = 0; i < bufs; i++) {
|
||||
|
||||
/* NANDFC buffer 0 is used for page read/write */
|
||||
writew(i, host->regs + NFC_BUF_ADDR);
|
||||
writew(i, NFC_V1_V2_BUF_ADDR);
|
||||
|
||||
writew(ops, host->regs + NFC_CONFIG2);
|
||||
writew(ops, NFC_V1_V2_CONFIG2);
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(host, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_read_id_v3(struct mxc_nand_host *host)
|
||||
{
|
||||
/* Read ID into main buffer */
|
||||
writel(NFC_ID, NFC_V3_LAUNCH);
|
||||
|
||||
wait_op_done(host, true);
|
||||
|
||||
memcpy(host->data_buf, host->main_area0, 16);
|
||||
}
|
||||
|
||||
/* Request the NANDFC to perform a read of the NAND device ID. */
|
||||
static void send_read_id(struct mxc_nand_host *host)
|
||||
static void send_read_id_v1_v2(struct mxc_nand_host *host)
|
||||
{
|
||||
struct nand_chip *this = &host->nand;
|
||||
|
||||
/* NANDFC buffer 0 is used for device ID output */
|
||||
writew(0x0, host->regs + NFC_BUF_ADDR);
|
||||
writew(0x0, NFC_V1_V2_BUF_ADDR);
|
||||
|
||||
writew(NFC_ID, host->regs + NFC_CONFIG2);
|
||||
writew(NFC_ID, NFC_V1_V2_CONFIG2);
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(host, true);
|
||||
@ -301,29 +414,36 @@ static void send_read_id(struct mxc_nand_host *host)
|
||||
memcpy(host->data_buf, host->main_area0, 16);
|
||||
}
|
||||
|
||||
/* This function requests the NANDFC to perform a read of the
|
||||
* NAND device status and returns the current status. */
|
||||
static uint16_t get_dev_status(struct mxc_nand_host *host)
|
||||
static uint16_t get_dev_status_v3(struct mxc_nand_host *host)
|
||||
{
|
||||
void __iomem *main_buf = host->main_area1;
|
||||
uint32_t store;
|
||||
uint16_t ret;
|
||||
/* Issue status request to NAND device */
|
||||
|
||||
/* store the main area1 first word, later do recovery */
|
||||
store = readl(main_buf);
|
||||
/* NANDFC buffer 1 is used for device status to prevent
|
||||
* corruption of read/write buffer on status requests. */
|
||||
writew(1, host->regs + NFC_BUF_ADDR);
|
||||
|
||||
writew(NFC_STATUS, host->regs + NFC_CONFIG2);
|
||||
|
||||
/* Wait for operation to complete */
|
||||
writew(NFC_STATUS, NFC_V3_LAUNCH);
|
||||
wait_op_done(host, true);
|
||||
|
||||
return readl(NFC_V3_CONFIG1) >> 16;
|
||||
}
|
||||
|
||||
/* This function requests the NANDFC to perform a read of the
|
||||
* NAND device status and returns the current status. */
|
||||
static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
|
||||
{
|
||||
void __iomem *main_buf = host->main_area0;
|
||||
uint32_t store;
|
||||
uint16_t ret;
|
||||
|
||||
writew(0x0, NFC_V1_V2_BUF_ADDR);
|
||||
|
||||
/*
|
||||
* The device status is stored in main_area0. To
|
||||
* prevent corruption of the buffer save the value
|
||||
* and restore it afterwards.
|
||||
*/
|
||||
store = readl(main_buf);
|
||||
|
||||
writew(NFC_STATUS, NFC_V1_V2_CONFIG2);
|
||||
wait_op_done(host, true);
|
||||
|
||||
/* Status is placed in first word of main buffer */
|
||||
/* get status, then recovery area 1 data */
|
||||
ret = readw(main_buf);
|
||||
|
||||
writel(store, main_buf);
|
||||
|
||||
return ret;
|
||||
@ -347,7 +467,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
|
||||
*/
|
||||
}
|
||||
|
||||
static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
|
||||
static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
|
||||
u_char *read_ecc, u_char *calc_ecc)
|
||||
{
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
@ -358,7 +478,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
|
||||
* additional correction. 2-Bit errors cannot be corrected by
|
||||
* HW ECC, so we need to return failure
|
||||
*/
|
||||
uint16_t ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT);
|
||||
uint16_t ecc_status = readw(NFC_V1_V2_ECC_STATUS_RESULT);
|
||||
|
||||
if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
|
||||
DEBUG(MTD_DEBUG_LEVEL0,
|
||||
@ -369,6 +489,43 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
|
||||
u_char *read_ecc, u_char *calc_ecc)
|
||||
{
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
struct mxc_nand_host *host = nand_chip->priv;
|
||||
u32 ecc_stat, err;
|
||||
int no_subpages = 1;
|
||||
int ret = 0;
|
||||
u8 ecc_bit_mask, err_limit;
|
||||
|
||||
ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
|
||||
err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
|
||||
|
||||
no_subpages = mtd->writesize >> 9;
|
||||
|
||||
if (nfc_is_v21())
|
||||
ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
|
||||
else
|
||||
ecc_stat = readl(NFC_V3_ECC_STATUS_RESULT);
|
||||
|
||||
do {
|
||||
err = ecc_stat & ecc_bit_mask;
|
||||
if (err > err_limit) {
|
||||
printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
|
||||
return -1;
|
||||
} else {
|
||||
ret += err;
|
||||
}
|
||||
ecc_stat >>= 4;
|
||||
} while (--no_subpages);
|
||||
|
||||
mtd->ecc_stats.corrected += ret;
|
||||
pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
|
||||
u_char *ecc_code)
|
||||
{
|
||||
@ -383,7 +540,7 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd)
|
||||
|
||||
/* Check for status request */
|
||||
if (host->status_request)
|
||||
return get_dev_status(host) & 0xFF;
|
||||
return host->get_dev_status(host) & 0xFF;
|
||||
|
||||
ret = *(uint8_t *)(host->data_buf + host->buf_start);
|
||||
host->buf_start++;
|
||||
@ -519,71 +676,163 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
|
||||
* we will used the saved column address to index into
|
||||
* the full page.
|
||||
*/
|
||||
send_addr(host, 0, page_addr == -1);
|
||||
host->send_addr(host, 0, page_addr == -1);
|
||||
if (mtd->writesize > 512)
|
||||
/* another col addr cycle for 2k page */
|
||||
send_addr(host, 0, false);
|
||||
host->send_addr(host, 0, false);
|
||||
}
|
||||
|
||||
/* Write out page address, if necessary */
|
||||
if (page_addr != -1) {
|
||||
/* paddr_0 - p_addr_7 */
|
||||
send_addr(host, (page_addr & 0xff), false);
|
||||
host->send_addr(host, (page_addr & 0xff), false);
|
||||
|
||||
if (mtd->writesize > 512) {
|
||||
if (mtd->size >= 0x10000000) {
|
||||
/* paddr_8 - paddr_15 */
|
||||
send_addr(host, (page_addr >> 8) & 0xff, false);
|
||||
send_addr(host, (page_addr >> 16) & 0xff, true);
|
||||
host->send_addr(host, (page_addr >> 8) & 0xff, false);
|
||||
host->send_addr(host, (page_addr >> 16) & 0xff, true);
|
||||
} else
|
||||
/* paddr_8 - paddr_15 */
|
||||
send_addr(host, (page_addr >> 8) & 0xff, true);
|
||||
host->send_addr(host, (page_addr >> 8) & 0xff, true);
|
||||
} else {
|
||||
/* One more address cycle for higher density devices */
|
||||
if (mtd->size >= 0x4000000) {
|
||||
/* paddr_8 - paddr_15 */
|
||||
send_addr(host, (page_addr >> 8) & 0xff, false);
|
||||
send_addr(host, (page_addr >> 16) & 0xff, true);
|
||||
host->send_addr(host, (page_addr >> 8) & 0xff, false);
|
||||
host->send_addr(host, (page_addr >> 16) & 0xff, true);
|
||||
} else
|
||||
/* paddr_8 - paddr_15 */
|
||||
send_addr(host, (page_addr >> 8) & 0xff, true);
|
||||
host->send_addr(host, (page_addr >> 8) & 0xff, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void preset(struct mtd_info *mtd)
|
||||
/*
|
||||
* v2 and v3 type controllers can do 4bit or 8bit ecc depending
|
||||
* on how much oob the nand chip has. For 8bit ecc we need at least
|
||||
* 26 bytes of oob data per 512 byte block.
|
||||
*/
|
||||
static int get_eccsize(struct mtd_info *mtd)
|
||||
{
|
||||
int oobbytes_per_512 = 0;
|
||||
|
||||
oobbytes_per_512 = mtd->oobsize * 512 / mtd->writesize;
|
||||
|
||||
if (oobbytes_per_512 < 26)
|
||||
return 4;
|
||||
else
|
||||
return 8;
|
||||
}
|
||||
|
||||
static void preset_v1_v2(struct mtd_info *mtd)
|
||||
{
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
struct mxc_nand_host *host = nand_chip->priv;
|
||||
uint16_t tmp;
|
||||
|
||||
/* enable interrupt, disable spare enable */
|
||||
tmp = readw(host->regs + NFC_CONFIG1);
|
||||
tmp &= ~NFC_INT_MSK;
|
||||
tmp &= ~NFC_SP_EN;
|
||||
tmp = readw(NFC_V1_V2_CONFIG1);
|
||||
tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK;
|
||||
tmp &= ~NFC_V1_V2_CONFIG1_SP_EN;
|
||||
if (nand_chip->ecc.mode == NAND_ECC_HW) {
|
||||
tmp |= NFC_ECC_EN;
|
||||
tmp |= NFC_V1_V2_CONFIG1_ECC_EN;
|
||||
} else {
|
||||
tmp &= ~NFC_ECC_EN;
|
||||
tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
|
||||
}
|
||||
writew(tmp, host->regs + NFC_CONFIG1);
|
||||
|
||||
if (nfc_is_v21() && mtd->writesize) {
|
||||
host->eccsize = get_eccsize(mtd);
|
||||
if (host->eccsize == 4)
|
||||
tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
|
||||
} else {
|
||||
host->eccsize = 1;
|
||||
}
|
||||
|
||||
writew(tmp, NFC_V1_V2_CONFIG1);
|
||||
/* preset operation */
|
||||
|
||||
/* Unlock the internal RAM Buffer */
|
||||
writew(0x2, host->regs + NFC_CONFIG);
|
||||
writew(0x2, NFC_V1_V2_CONFIG);
|
||||
|
||||
/* Blocks to be unlocked */
|
||||
if (nfc_is_v21()) {
|
||||
writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
|
||||
writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
|
||||
writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR);
|
||||
writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR);
|
||||
} else if (nfc_is_v1()) {
|
||||
writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
|
||||
writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
|
||||
writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
|
||||
writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR);
|
||||
} else
|
||||
BUG();
|
||||
|
||||
/* Unlock Block Command for given address range */
|
||||
writew(0x4, host->regs + NFC_WRPROT);
|
||||
writew(0x4, NFC_V1_V2_WRPROT);
|
||||
}
|
||||
|
||||
static void preset_v3(struct mtd_info *mtd)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
struct mxc_nand_host *host = chip->priv;
|
||||
uint32_t config2, config3;
|
||||
int i, addr_phases;
|
||||
|
||||
writel(NFC_V3_CONFIG1_RBA(0), NFC_V3_CONFIG1);
|
||||
writel(NFC_V3_IPC_CREQ, NFC_V3_IPC);
|
||||
|
||||
/* Unlock the internal RAM Buffer */
|
||||
writel(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_UNLOCK,
|
||||
NFC_V3_WRPROT);
|
||||
|
||||
/* Blocks to be unlocked */
|
||||
for (i = 0; i < NAND_MAX_CHIPS; i++)
|
||||
writel(0x0 | (0xffff << 16),
|
||||
NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2));
|
||||
|
||||
writel(0, NFC_V3_IPC);
|
||||
|
||||
config2 = NFC_V3_CONFIG2_ONE_CYCLE |
|
||||
NFC_V3_CONFIG2_2CMD_PHASES |
|
||||
NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) |
|
||||
NFC_V3_CONFIG2_ST_CMD(0x70) |
|
||||
NFC_V3_CONFIG2_NUM_ADDR_PHASE0;
|
||||
|
||||
if (chip->ecc.mode == NAND_ECC_HW)
|
||||
config2 |= NFC_V3_CONFIG2_ECC_EN;
|
||||
|
||||
addr_phases = fls(chip->pagemask) >> 3;
|
||||
|
||||
if (mtd->writesize == 2048) {
|
||||
config2 |= NFC_V3_CONFIG2_PS_2048;
|
||||
config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases);
|
||||
} else if (mtd->writesize == 4096) {
|
||||
config2 |= NFC_V3_CONFIG2_PS_4096;
|
||||
config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases);
|
||||
} else {
|
||||
config2 |= NFC_V3_CONFIG2_PS_512;
|
||||
config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases - 1);
|
||||
}
|
||||
|
||||
if (mtd->writesize) {
|
||||
config2 |= NFC_V3_CONFIG2_PPB(ffs(mtd->erasesize / mtd->writesize) - 6);
|
||||
host->eccsize = get_eccsize(mtd);
|
||||
if (host->eccsize == 8)
|
||||
config2 |= NFC_V3_CONFIG2_ECC_MODE_8;
|
||||
}
|
||||
|
||||
writel(config2, NFC_V3_CONFIG2);
|
||||
|
||||
config3 = NFC_V3_CONFIG3_NUM_OF_DEVICES(0) |
|
||||
NFC_V3_CONFIG3_NO_SDMA |
|
||||
NFC_V3_CONFIG3_RBB_MODE |
|
||||
NFC_V3_CONFIG3_SBB(6) | /* Reset default */
|
||||
NFC_V3_CONFIG3_ADD_OP(0);
|
||||
|
||||
if (!(chip->options & NAND_BUSWIDTH_16))
|
||||
config3 |= NFC_V3_CONFIG3_FW8;
|
||||
|
||||
writel(config3, NFC_V3_CONFIG3);
|
||||
|
||||
writel(0, NFC_V3_DELAY_LINE);
|
||||
}
|
||||
|
||||
/* Used by the upper layer to write command to NAND Flash for
|
||||
@ -604,15 +853,15 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
|
||||
/* Command pre-processing step */
|
||||
switch (command) {
|
||||
case NAND_CMD_RESET:
|
||||
send_cmd(host, command, false);
|
||||
preset(mtd);
|
||||
host->preset(mtd);
|
||||
host->send_cmd(host, command, false);
|
||||
break;
|
||||
|
||||
case NAND_CMD_STATUS:
|
||||
host->buf_start = 0;
|
||||
host->status_request = true;
|
||||
|
||||
send_cmd(host, command, true);
|
||||
host->send_cmd(host, command, true);
|
||||
mxc_do_addr_cycle(mtd, column, page_addr);
|
||||
break;
|
||||
|
||||
@ -625,13 +874,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
|
||||
|
||||
command = NAND_CMD_READ0; /* only READ0 is valid */
|
||||
|
||||
send_cmd(host, command, false);
|
||||
host->send_cmd(host, command, false);
|
||||
mxc_do_addr_cycle(mtd, column, page_addr);
|
||||
|
||||
if (mtd->writesize > 512)
|
||||
send_cmd(host, NAND_CMD_READSTART, true);
|
||||
host->send_cmd(host, NAND_CMD_READSTART, true);
|
||||
|
||||
send_page(mtd, NFC_OUTPUT);
|
||||
host->send_page(mtd, NFC_OUTPUT);
|
||||
|
||||
memcpy(host->data_buf, host->main_area0, mtd->writesize);
|
||||
copy_spare(mtd, true);
|
||||
@ -644,28 +893,28 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
|
||||
|
||||
host->buf_start = column;
|
||||
|
||||
send_cmd(host, command, false);
|
||||
host->send_cmd(host, command, false);
|
||||
mxc_do_addr_cycle(mtd, column, page_addr);
|
||||
break;
|
||||
|
||||
case NAND_CMD_PAGEPROG:
|
||||
memcpy(host->main_area0, host->data_buf, mtd->writesize);
|
||||
copy_spare(mtd, false);
|
||||
send_page(mtd, NFC_INPUT);
|
||||
send_cmd(host, command, true);
|
||||
host->send_page(mtd, NFC_INPUT);
|
||||
host->send_cmd(host, command, true);
|
||||
mxc_do_addr_cycle(mtd, column, page_addr);
|
||||
break;
|
||||
|
||||
case NAND_CMD_READID:
|
||||
send_cmd(host, command, true);
|
||||
host->send_cmd(host, command, true);
|
||||
mxc_do_addr_cycle(mtd, column, page_addr);
|
||||
send_read_id(host);
|
||||
host->send_read_id(host);
|
||||
host->buf_start = column;
|
||||
break;
|
||||
|
||||
case NAND_CMD_ERASE1:
|
||||
case NAND_CMD_ERASE2:
|
||||
send_cmd(host, command, false);
|
||||
host->send_cmd(host, command, false);
|
||||
mxc_do_addr_cycle(mtd, column, page_addr);
|
||||
|
||||
break;
|
||||
@ -761,22 +1010,55 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
host->main_area0 = host->base;
|
||||
host->main_area1 = host->base + 0x200;
|
||||
|
||||
if (nfc_is_v1() || nfc_is_v21()) {
|
||||
host->preset = preset_v1_v2;
|
||||
host->send_cmd = send_cmd_v1_v2;
|
||||
host->send_addr = send_addr_v1_v2;
|
||||
host->send_page = send_page_v1_v2;
|
||||
host->send_read_id = send_read_id_v1_v2;
|
||||
host->get_dev_status = get_dev_status_v1_v2;
|
||||
host->check_int = check_int_v1_v2;
|
||||
}
|
||||
|
||||
if (nfc_is_v21()) {
|
||||
host->regs = host->base + 0x1000;
|
||||
host->regs = host->base + 0x1e00;
|
||||
host->spare0 = host->base + 0x1000;
|
||||
host->spare_len = 64;
|
||||
oob_smallpage = &nandv2_hw_eccoob_smallpage;
|
||||
oob_largepage = &nandv2_hw_eccoob_largepage;
|
||||
this->ecc.bytes = 9;
|
||||
} else if (nfc_is_v1()) {
|
||||
host->regs = host->base;
|
||||
host->regs = host->base + 0xe00;
|
||||
host->spare0 = host->base + 0x800;
|
||||
host->spare_len = 16;
|
||||
oob_smallpage = &nandv1_hw_eccoob_smallpage;
|
||||
oob_largepage = &nandv1_hw_eccoob_largepage;
|
||||
this->ecc.bytes = 3;
|
||||
host->eccsize = 1;
|
||||
} else if (nfc_is_v3_2()) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!res) {
|
||||
err = -ENODEV;
|
||||
goto eirq;
|
||||
}
|
||||
host->regs_ip = ioremap(res->start, resource_size(res));
|
||||
if (!host->regs_ip) {
|
||||
err = -ENOMEM;
|
||||
goto eirq;
|
||||
}
|
||||
host->regs_axi = host->base + 0x1e00;
|
||||
host->spare0 = host->base + 0x1000;
|
||||
host->spare_len = 64;
|
||||
host->preset = preset_v3;
|
||||
host->send_cmd = send_cmd_v3;
|
||||
host->send_addr = send_addr_v3;
|
||||
host->send_page = send_page_v3;
|
||||
host->send_read_id = send_read_id_v3;
|
||||
host->check_int = check_int_v3;
|
||||
host->get_dev_status = get_dev_status_v3;
|
||||
oob_smallpage = &nandv2_hw_eccoob_smallpage;
|
||||
oob_largepage = &nandv2_hw_eccoob_largepage;
|
||||
} else
|
||||
BUG();
|
||||
|
||||
@ -786,7 +1068,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
if (pdata->hw_ecc) {
|
||||
this->ecc.calculate = mxc_nand_calculate_ecc;
|
||||
this->ecc.hwctl = mxc_nand_enable_hwecc;
|
||||
this->ecc.correct = mxc_nand_correct_data;
|
||||
if (nfc_is_v1())
|
||||
this->ecc.correct = mxc_nand_correct_data_v1;
|
||||
else
|
||||
this->ecc.correct = mxc_nand_correct_data_v2_v3;
|
||||
this->ecc.mode = NAND_ECC_HW;
|
||||
} else {
|
||||
this->ecc.mode = NAND_ECC_SOFT;
|
||||
@ -817,6 +1102,9 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
goto escan;
|
||||
}
|
||||
|
||||
/* Call preset again, with correct writesize this time */
|
||||
host->preset(mtd);
|
||||
|
||||
if (mtd->writesize == 2048)
|
||||
this->ecc.layout = oob_largepage;
|
||||
|
||||
@ -848,6 +1136,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
escan:
|
||||
free_irq(host->irq, host);
|
||||
eirq:
|
||||
if (host->regs_ip)
|
||||
iounmap(host->regs_ip);
|
||||
iounmap(host->base);
|
||||
eres:
|
||||
clk_put(host->clk);
|
||||
@ -867,59 +1157,19 @@ static int __devexit mxcnd_remove(struct platform_device *pdev)
|
||||
|
||||
nand_release(&host->mtd);
|
||||
free_irq(host->irq, host);
|
||||
if (host->regs_ip)
|
||||
iounmap(host->regs_ip);
|
||||
iounmap(host->base);
|
||||
kfree(host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct mtd_info *mtd = platform_get_drvdata(pdev);
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
struct mxc_nand_host *host = nand_chip->priv;
|
||||
int ret = 0;
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n");
|
||||
|
||||
ret = mtd->suspend(mtd);
|
||||
|
||||
/*
|
||||
* nand_suspend locks the device for exclusive access, so
|
||||
* the clock must already be off.
|
||||
*/
|
||||
BUG_ON(!ret && host->clk_act);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxcnd_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct mtd_info *mtd = platform_get_drvdata(pdev);
|
||||
struct nand_chip *nand_chip = mtd->priv;
|
||||
struct mxc_nand_host *host = nand_chip->priv;
|
||||
int ret = 0;
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n");
|
||||
|
||||
mtd->resume(mtd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
# define mxcnd_suspend NULL
|
||||
# define mxcnd_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct platform_driver mxcnd_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
},
|
||||
},
|
||||
.remove = __devexit_p(mxcnd_remove),
|
||||
.suspend = mxcnd_suspend,
|
||||
.resume = mxcnd_resume,
|
||||
};
|
||||
|
||||
static int __init mxc_nd_init(void)
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/nand_ecc.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/leds.h>
|
||||
@ -347,7 +346,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
u16 bad;
|
||||
|
||||
if (chip->options & NAND_BB_LAST_PAGE)
|
||||
if (chip->options & NAND_BBT_SCANLASTPAGE)
|
||||
ofs += mtd->erasesize - mtd->writesize;
|
||||
|
||||
page = (int)(ofs >> chip->page_shift) & chip->pagemask;
|
||||
@ -397,9 +396,9 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
uint8_t buf[2] = { 0, 0 };
|
||||
int block, ret;
|
||||
int block, ret, i = 0;
|
||||
|
||||
if (chip->options & NAND_BB_LAST_PAGE)
|
||||
if (chip->options & NAND_BBT_SCANLASTPAGE)
|
||||
ofs += mtd->erasesize - mtd->writesize;
|
||||
|
||||
/* Get block number */
|
||||
@ -411,17 +410,31 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
if (chip->options & NAND_USE_FLASH_BBT)
|
||||
ret = nand_update_bbt(mtd, ofs);
|
||||
else {
|
||||
/* We write two bytes, so we dont have to mess with 16 bit
|
||||
* access
|
||||
*/
|
||||
nand_get_device(chip, mtd, FL_WRITING);
|
||||
ofs += mtd->oobsize;
|
||||
chip->ops.len = chip->ops.ooblen = 2;
|
||||
chip->ops.datbuf = NULL;
|
||||
chip->ops.oobbuf = buf;
|
||||
chip->ops.ooboffs = chip->badblockpos & ~0x01;
|
||||
|
||||
ret = nand_do_write_oob(mtd, ofs, &chip->ops);
|
||||
/* Write to first two pages and to byte 1 and 6 if necessary.
|
||||
* If we write to more than one location, the first error
|
||||
* encountered quits the procedure. We write two bytes per
|
||||
* location, so we dont have to mess with 16 bit access.
|
||||
*/
|
||||
do {
|
||||
chip->ops.len = chip->ops.ooblen = 2;
|
||||
chip->ops.datbuf = NULL;
|
||||
chip->ops.oobbuf = buf;
|
||||
chip->ops.ooboffs = chip->badblockpos & ~0x01;
|
||||
|
||||
ret = nand_do_write_oob(mtd, ofs, &chip->ops);
|
||||
|
||||
if (!ret && (chip->options & NAND_BBT_SCANBYTE1AND6)) {
|
||||
chip->ops.ooboffs = NAND_SMALL_BADBLOCK_POS
|
||||
& ~0x01;
|
||||
ret = nand_do_write_oob(mtd, ofs, &chip->ops);
|
||||
}
|
||||
i++;
|
||||
ofs += mtd->writesize;
|
||||
} while (!ret && (chip->options & NAND_BBT_SCAN2NDPAGE) &&
|
||||
i < 2);
|
||||
|
||||
nand_release_device(mtd);
|
||||
}
|
||||
if (!ret)
|
||||
@ -2920,9 +2933,14 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
|
||||
chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1;
|
||||
|
||||
/* Set the bad block position */
|
||||
chip->badblockpos = mtd->writesize > 512 ?
|
||||
NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
|
||||
chip->badblockbits = 8;
|
||||
if (!(busw & NAND_BUSWIDTH_16) && (*maf_id == NAND_MFR_STMICRO ||
|
||||
(*maf_id == NAND_MFR_SAMSUNG &&
|
||||
mtd->writesize == 512) ||
|
||||
*maf_id == NAND_MFR_AMD))
|
||||
chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
|
||||
else
|
||||
chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
|
||||
|
||||
|
||||
/* Get chip options, preserve non chip based options */
|
||||
chip->options &= ~NAND_CHIPOPTIONS_MSK;
|
||||
@ -2941,12 +2959,32 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
|
||||
|
||||
/*
|
||||
* Bad block marker is stored in the last page of each block
|
||||
* on Samsung and Hynix MLC devices
|
||||
* on Samsung and Hynix MLC devices; stored in first two pages
|
||||
* of each block on Micron devices with 2KiB pages and on
|
||||
* SLC Samsung, Hynix, and AMD/Spansion. All others scan only
|
||||
* the first page.
|
||||
*/
|
||||
if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
|
||||
(*maf_id == NAND_MFR_SAMSUNG ||
|
||||
*maf_id == NAND_MFR_HYNIX))
|
||||
chip->options |= NAND_BB_LAST_PAGE;
|
||||
chip->options |= NAND_BBT_SCANLASTPAGE;
|
||||
else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
|
||||
(*maf_id == NAND_MFR_SAMSUNG ||
|
||||
*maf_id == NAND_MFR_HYNIX ||
|
||||
*maf_id == NAND_MFR_AMD)) ||
|
||||
(mtd->writesize == 2048 &&
|
||||
*maf_id == NAND_MFR_MICRON))
|
||||
chip->options |= NAND_BBT_SCAN2NDPAGE;
|
||||
|
||||
/*
|
||||
* Numonyx/ST 2K pages, x8 bus use BOTH byte 1 and 6
|
||||
*/
|
||||
if (!(busw & NAND_BUSWIDTH_16) &&
|
||||
*maf_id == NAND_MFR_STMICRO &&
|
||||
mtd->writesize == 2048) {
|
||||
chip->options |= NAND_BBT_SCANBYTE1AND6;
|
||||
chip->badblockpos = 0;
|
||||
}
|
||||
|
||||
/* Check for AND chips with 4 page planes */
|
||||
if (chip->options & NAND_4PAGE_ARRAY)
|
||||
@ -3306,6 +3344,11 @@ void nand_release(struct mtd_info *mtd)
|
||||
kfree(chip->bbt);
|
||||
if (!(chip->options & NAND_OWN_BUFFERS))
|
||||
kfree(chip->buffers);
|
||||
|
||||
/* Free bad block descriptor memory */
|
||||
if (chip->badblock_pattern && chip->badblock_pattern->options
|
||||
& NAND_BBT_DYNAMICSTRUCT)
|
||||
kfree(chip->badblock_pattern);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(nand_lock);
|
||||
|
@ -55,7 +55,6 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/nand_ecc.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/vmalloc.h>
|
||||
@ -93,6 +92,28 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check both positions 1 and 6 for pattern? */
|
||||
if (td->options & NAND_BBT_SCANBYTE1AND6) {
|
||||
if (td->options & NAND_BBT_SCANEMPTY) {
|
||||
p += td->len;
|
||||
end += NAND_SMALL_BADBLOCK_POS - td->offs;
|
||||
/* Check region between positions 1 and 6 */
|
||||
for (i = 0; i < NAND_SMALL_BADBLOCK_POS - td->offs - td->len;
|
||||
i++) {
|
||||
if (*p++ != 0xff)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
p += NAND_SMALL_BADBLOCK_POS - td->offs;
|
||||
}
|
||||
/* Compare the pattern */
|
||||
for (i = 0; i < td->len; i++) {
|
||||
if (p[i] != td->pattern[i])
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (td->options & NAND_BBT_SCANEMPTY) {
|
||||
p += td->len;
|
||||
end += td->len;
|
||||
@ -124,6 +145,13 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
|
||||
if (p[td->offs + i] != td->pattern[i])
|
||||
return -1;
|
||||
}
|
||||
/* Need to check location 1 AND 6? */
|
||||
if (td->options & NAND_BBT_SCANBYTE1AND6) {
|
||||
for (i = 0; i < td->len; i++) {
|
||||
if (p[NAND_SMALL_BADBLOCK_POS + i] != td->pattern[i])
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -397,12 +425,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
|
||||
|
||||
if (bd->options & NAND_BBT_SCANALLPAGES)
|
||||
len = 1 << (this->bbt_erase_shift - this->page_shift);
|
||||
else {
|
||||
if (bd->options & NAND_BBT_SCAN2NDPAGE)
|
||||
len = 2;
|
||||
else
|
||||
len = 1;
|
||||
}
|
||||
else if (bd->options & NAND_BBT_SCAN2NDPAGE)
|
||||
len = 2;
|
||||
else
|
||||
len = 1;
|
||||
|
||||
if (!(bd->options & NAND_BBT_SCANEMPTY)) {
|
||||
/* We need only read few bytes from the OOB area */
|
||||
@ -432,7 +458,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
|
||||
from = (loff_t)startblock << (this->bbt_erase_shift - 1);
|
||||
}
|
||||
|
||||
if (this->options & NAND_BB_LAST_PAGE)
|
||||
if (this->options & NAND_BBT_SCANLASTPAGE)
|
||||
from += mtd->erasesize - (mtd->writesize * len);
|
||||
|
||||
for (i = startblock; i < numblocks;) {
|
||||
@ -1092,30 +1118,16 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
|
||||
* while scanning a device for factory marked good / bad blocks. */
|
||||
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
|
||||
|
||||
static struct nand_bbt_descr smallpage_memorybased = {
|
||||
.options = NAND_BBT_SCAN2NDPAGE,
|
||||
.offs = 5,
|
||||
.len = 1,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr largepage_memorybased = {
|
||||
.options = 0,
|
||||
.offs = 0,
|
||||
.len = 2,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr smallpage_flashbased = {
|
||||
.options = NAND_BBT_SCAN2NDPAGE,
|
||||
.offs = 5,
|
||||
.offs = NAND_SMALL_BADBLOCK_POS,
|
||||
.len = 1,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr largepage_flashbased = {
|
||||
.options = NAND_BBT_SCAN2NDPAGE,
|
||||
.offs = 0,
|
||||
.offs = NAND_LARGE_BADBLOCK_POS,
|
||||
.len = 2,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
@ -1154,6 +1166,43 @@ static struct nand_bbt_descr bbt_mirror_descr = {
|
||||
.pattern = mirror_pattern
|
||||
};
|
||||
|
||||
#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
|
||||
NAND_BBT_SCANBYTE1AND6)
|
||||
/**
|
||||
* nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure
|
||||
* @this: NAND chip to create descriptor for
|
||||
*
|
||||
* This function allocates and initializes a nand_bbt_descr for BBM detection
|
||||
* based on the properties of "this". The new descriptor is stored in
|
||||
* this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
|
||||
* passed to this function.
|
||||
*
|
||||
* TODO: Handle other flags, replace other static structs
|
||||
* (e.g. handle NAND_BBT_FLASH for flash-based BBT,
|
||||
* replace smallpage_flashbased)
|
||||
*
|
||||
*/
|
||||
static int nand_create_default_bbt_descr(struct nand_chip *this)
|
||||
{
|
||||
struct nand_bbt_descr *bd;
|
||||
if (this->badblock_pattern) {
|
||||
printk(KERN_WARNING "BBT descr already allocated; not replacing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
bd = kzalloc(sizeof(*bd), GFP_KERNEL);
|
||||
if (!bd) {
|
||||
printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
bd->options = this->options & BBT_SCAN_OPTIONS;
|
||||
bd->offs = this->badblockpos;
|
||||
bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1;
|
||||
bd->pattern = scan_ff_pattern;
|
||||
bd->options |= NAND_BBT_DYNAMICSTRUCT;
|
||||
this->badblock_pattern = bd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nand_default_bbt - [NAND Interface] Select a default bad block table for the device
|
||||
* @mtd: MTD device structure
|
||||
@ -1196,10 +1245,8 @@ int nand_default_bbt(struct mtd_info *mtd)
|
||||
} else {
|
||||
this->bbt_td = NULL;
|
||||
this->bbt_md = NULL;
|
||||
if (!this->badblock_pattern) {
|
||||
this->badblock_pattern = (mtd->writesize > 512) ?
|
||||
&largepage_memorybased : &smallpage_memorybased;
|
||||
}
|
||||
if (!this->badblock_pattern)
|
||||
nand_create_default_bbt_descr(this);
|
||||
}
|
||||
return nand_scan_bbt(mtd, this->badblock_pattern);
|
||||
}
|
||||
|
@ -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 1,8V 16-bit", 0xB1, 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 */
|
||||
{"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS},
|
||||
@ -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 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
|
||||
* 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)
|
||||
*/
|
||||
static int init_nandsim(struct mtd_info *mtd)
|
||||
{
|
||||
struct nand_chip *chip = (struct nand_chip *)mtd->priv;
|
||||
struct nandsim *ns = (struct nandsim *)(chip->priv);
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
struct nandsim *ns = chip->priv;
|
||||
int i, ret = 0;
|
||||
uint64_t remains;
|
||||
uint64_t next_offset;
|
||||
@ -1877,7 +1877,7 @@ static void switch_state(struct nandsim *ns)
|
||||
|
||||
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;
|
||||
|
||||
/* Sanity and correctness checks */
|
||||
@ -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)
|
||||
{
|
||||
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
|
||||
struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
|
||||
|
||||
/* Sanity and correctness checks */
|
||||
if (!ns->lines.ce) {
|
||||
@ -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)
|
||||
{
|
||||
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 */
|
||||
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)
|
||||
|
||||
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 */
|
||||
if (!ns->lines.ce) {
|
||||
@ -2352,7 +2352,7 @@ module_init(ns_init_module);
|
||||
*/
|
||||
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;
|
||||
|
||||
free_nandsim(ns); /* Free nandsim private resources */
|
||||
|
@ -91,7 +91,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Scan to find existance of the device */
|
||||
if (nand_scan(&data->mtd, 1)) {
|
||||
if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {
|
||||
err = -ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
@ -64,8 +64,8 @@ static inline void r852_write_reg_dword(struct r852_device *dev,
|
||||
/* returns pointer to our private structure */
|
||||
static inline struct r852_device *r852_get_dev(struct mtd_info *mtd)
|
||||
{
|
||||
struct nand_chip *chip = (struct nand_chip *)mtd->priv;
|
||||
return (struct r852_device *)chip->priv;
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
return chip->priv;
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
struct r852_device *dev = (struct r852_device *)chip->priv;
|
||||
struct r852_device *dev = chip->priv;
|
||||
|
||||
unsigned long timeout;
|
||||
int status;
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <linux/rslib.h>
|
||||
#include <linux/bitrev.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
@ -727,15 +727,12 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
|
||||
if (set == NULL)
|
||||
return add_mtd_device(&mtd->mtd);
|
||||
|
||||
if (set->nr_partitions == 0) {
|
||||
mtd->mtd.name = set->name;
|
||||
nr_part = parse_mtd_partitions(&mtd->mtd, part_probes,
|
||||
&part_info, 0);
|
||||
} else {
|
||||
if (set->nr_partitions > 0 && set->partitions != NULL) {
|
||||
nr_part = set->nr_partitions;
|
||||
part_info = set->partitions;
|
||||
}
|
||||
mtd->mtd.name = set->name;
|
||||
nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, &part_info, 0);
|
||||
|
||||
if (nr_part <= 0 && set->nr_partitions > 0) {
|
||||
nr_part = set->nr_partitions;
|
||||
part_info = set->partitions;
|
||||
}
|
||||
|
||||
if (nr_part > 0 && part_info)
|
||||
|
@ -109,7 +109,7 @@ static struct nand_flash_dev nand_xd_flash_ids[] = {
|
||||
|
||||
int sm_register_device(struct mtd_info *mtd, int smartmedia)
|
||||
{
|
||||
struct nand_chip *chip = (struct nand_chip *)mtd->priv;
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
int ret;
|
||||
|
||||
chip->options |= NAND_SKIP_BBTSCAN;
|
||||
|
@ -1,11 +1,22 @@
|
||||
/* Linux driver for NAND Flash Translation Layer */
|
||||
/* (c) 1999 Machine Vision Holdings, Inc. */
|
||||
/* Author: David Woodhouse <dwmw2@infradead.org> */
|
||||
|
||||
/*
|
||||
The contents of this file are distributed under the GNU General
|
||||
Public License version 2. The author places no additional
|
||||
restrictions of any kind on it.
|
||||
* Linux driver for NAND Flash Translation Layer
|
||||
*
|
||||
* Copyright © 1999 Machine Vision Holdings, Inc.
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define PRERELEASE
|
||||
|
@ -2,7 +2,8 @@
|
||||
* NFTL mount code with extensive checks
|
||||
*
|
||||
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
|
||||
* Copyright (C) 2000 Netgem S.A.
|
||||
* Copyright © 2000 Netgem S.A.
|
||||
* 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
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Flash partitions described by the OF (or flattened) device tree
|
||||
*
|
||||
* Copyright (C) 2006 MontaVista Software Inc.
|
||||
* Copyright © 2006 MontaVista Software Inc.
|
||||
* Author: Vitaly Wool <vwool@ru.mvista.com>
|
||||
*
|
||||
* Revised to handle newer style flash binding by:
|
||||
* Copyright (C) 2007 David Gibson, IBM Corporation.
|
||||
* Copyright © 2007 David Gibson, IBM Corporation.
|
||||
*
|
||||
* 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
|
||||
|
@ -25,14 +25,14 @@ config MTD_ONENAND_GENERIC
|
||||
|
||||
config MTD_ONENAND_OMAP2
|
||||
tristate "OneNAND on OMAP2/OMAP3 support"
|
||||
depends on MTD_ONENAND && (ARCH_OMAP2 || ARCH_OMAP3)
|
||||
depends on ARCH_OMAP2 || ARCH_OMAP3
|
||||
help
|
||||
Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU
|
||||
via the GPMC memory controller.
|
||||
|
||||
config MTD_ONENAND_SAMSUNG
|
||||
tristate "OneNAND on Samsung SOC controller support"
|
||||
depends on MTD_ONENAND && (ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210)
|
||||
depends on ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
|
||||
help
|
||||
Support for a OneNAND flash device connected to an Samsung SOC
|
||||
S3C64XX/S5PC1XX controller.
|
||||
|
@ -377,8 +377,11 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
|
||||
|
||||
default:
|
||||
block = onenand_block(this, addr);
|
||||
page = (int) (addr - onenand_addr(this, block)) >> this->page_shift;
|
||||
|
||||
if (FLEXONENAND(this))
|
||||
page = (int) (addr - onenand_addr(this, block))>>\
|
||||
this->page_shift;
|
||||
else
|
||||
page = (int) (addr >> this->page_shift);
|
||||
if (ONENAND_IS_2PLANE(this)) {
|
||||
/* Make the even block number */
|
||||
block &= ~1;
|
||||
@ -3730,17 +3733,16 @@ int flexonenand_set_boundary(struct mtd_info *mtd, int die,
|
||||
}
|
||||
|
||||
/**
|
||||
* onenand_probe - [OneNAND Interface] Probe the OneNAND device
|
||||
* onenand_chip_probe - [OneNAND Interface] The generic chip probe
|
||||
* @param mtd MTD device structure
|
||||
*
|
||||
* OneNAND detection method:
|
||||
* Compare the values from command with ones from register
|
||||
*/
|
||||
static int onenand_probe(struct mtd_info *mtd)
|
||||
static int onenand_chip_probe(struct mtd_info *mtd)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
|
||||
int density;
|
||||
int bram_maf_id, bram_dev_id, maf_id, dev_id;
|
||||
int syscfg;
|
||||
|
||||
/* Save system configuration 1 */
|
||||
@ -3763,12 +3765,6 @@ static int onenand_probe(struct mtd_info *mtd)
|
||||
/* Restore system configuration 1 */
|
||||
this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
|
||||
|
||||
/* Workaround */
|
||||
if (syscfg & ONENAND_SYS_CFG1_SYNC_WRITE) {
|
||||
bram_maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
|
||||
bram_dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
|
||||
}
|
||||
|
||||
/* Check manufacturer ID */
|
||||
if (onenand_check_maf(bram_maf_id))
|
||||
return -ENXIO;
|
||||
@ -3776,13 +3772,35 @@ static int onenand_probe(struct mtd_info *mtd)
|
||||
/* Read manufacturer and device IDs from Register */
|
||||
maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
|
||||
dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
|
||||
ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
|
||||
this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
|
||||
|
||||
/* Check OneNAND device */
|
||||
if (maf_id != bram_maf_id || dev_id != bram_dev_id)
|
||||
return -ENXIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* onenand_probe - [OneNAND Interface] Probe the OneNAND device
|
||||
* @param mtd MTD device structure
|
||||
*/
|
||||
static int onenand_probe(struct mtd_info *mtd)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
int maf_id, dev_id, ver_id;
|
||||
int density;
|
||||
int ret;
|
||||
|
||||
ret = this->chip_probe(mtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Read manufacturer and device IDs from Register */
|
||||
maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
|
||||
dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
|
||||
ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
|
||||
this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
|
||||
|
||||
/* Flash device information */
|
||||
onenand_print_device_info(dev_id, ver_id);
|
||||
this->device_id = dev_id;
|
||||
@ -3909,6 +3927,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
|
||||
if (!this->unlock_all)
|
||||
this->unlock_all = onenand_unlock_all;
|
||||
|
||||
if (!this->chip_probe)
|
||||
this->chip_probe = onenand_chip_probe;
|
||||
|
||||
if (!this->read_bufferram)
|
||||
this->read_bufferram = onenand_read_bufferram;
|
||||
if (!this->write_bufferram)
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/onenand.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
/**
|
||||
* check_short_pattern - [GENERIC] check if a pattern is in the buffer
|
||||
|
@ -630,6 +630,12 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5pc110_chip_probe(struct mtd_info *mtd)
|
||||
{
|
||||
/* Now just return 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
|
||||
{
|
||||
unsigned int flags = INT_ACT | LOAD_CMP;
|
||||
@ -757,6 +763,7 @@ static void s3c_onenand_setup(struct mtd_info *mtd)
|
||||
/* Use generic onenand functions */
|
||||
onenand->cmd_map = s5pc1xx_cmd_map;
|
||||
this->read_bufferram = s5pc110_read_bufferram;
|
||||
this->chip_probe = s5pc110_chip_probe;
|
||||
return;
|
||||
} else {
|
||||
BUG();
|
||||
@ -781,7 +788,6 @@ static int s3c_onenand_probe(struct platform_device *pdev)
|
||||
struct mtd_info *mtd;
|
||||
struct resource *r;
|
||||
int size, err;
|
||||
unsigned long onenand_ctrl_cfg = 0;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
/* No need to check pdata. the platform data is optional */
|
||||
@ -900,14 +906,6 @@ static int s3c_onenand_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
onenand->phys_base = onenand->base_res->start;
|
||||
|
||||
onenand_ctrl_cfg = readl(onenand->dma_addr + 0x100);
|
||||
if ((onenand_ctrl_cfg & ONENAND_SYS_CFG1_SYNC_WRITE) &&
|
||||
onenand->dma_addr)
|
||||
writel(onenand_ctrl_cfg & ~ONENAND_SYS_CFG1_SYNC_WRITE,
|
||||
onenand->dma_addr + 0x100);
|
||||
else
|
||||
onenand_ctrl_cfg = 0;
|
||||
}
|
||||
|
||||
if (onenand_scan(mtd, 1)) {
|
||||
@ -915,10 +913,7 @@ static int s3c_onenand_probe(struct platform_device *pdev)
|
||||
goto scan_failed;
|
||||
}
|
||||
|
||||
if (onenand->type == TYPE_S5PC110) {
|
||||
if (onenand_ctrl_cfg && onenand->dma_addr)
|
||||
writel(onenand_ctrl_cfg, onenand->dma_addr + 0x100);
|
||||
} else {
|
||||
if (onenand->type != TYPE_S5PC110) {
|
||||
/* S3C doesn't handle subpage write */
|
||||
mtd->subpage_sft = 0;
|
||||
this->subpagesize = mtd->writesize;
|
||||
|
@ -1,6 +1,24 @@
|
||||
/*
|
||||
* Parse RedBoot-style Flash Image System (FIS) tables and
|
||||
* produce a Linux partition array to match.
|
||||
*
|
||||
* Copyright © 2001 Red Hat UK Limited
|
||||
* 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/kernel.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* rfd_ftl.c -- resident flash disk (flash translation layer)
|
||||
*
|
||||
* Copyright (C) 2005 Sean Young <sean@mess.org>
|
||||
* Copyright © 2005 Sean Young <sean@mess.org>
|
||||
*
|
||||
* This type of flash translation layer (FTL) is used by the Embedded BIOS
|
||||
* by General Software. It is known as the Resident Flash Disk (RFD), see:
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Linux driver for SSFDC Flash Translation Layer (Read only)
|
||||
* (c) 2005 Eptar srl
|
||||
* © 2005 Eptar srl
|
||||
* Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
|
||||
*
|
||||
* Based on NTFL and MTDBLOCK_RO drivers
|
||||
|
@ -310,7 +310,7 @@ static int crosstest(void)
|
||||
static int erasecrosstest(void)
|
||||
{
|
||||
size_t read = 0, written = 0;
|
||||
int err = 0, i, ebnum, ok = 1, ebnum2;
|
||||
int err = 0, i, ebnum, ebnum2;
|
||||
loff_t addr0;
|
||||
char *readbuf = twopages;
|
||||
|
||||
@ -357,8 +357,7 @@ static int erasecrosstest(void)
|
||||
if (memcmp(writebuf, readbuf, pgsize)) {
|
||||
printk(PRINT_PREF "verify failed!\n");
|
||||
errcnt += 1;
|
||||
ok = 0;
|
||||
return err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk(PRINT_PREF "erasing block %d\n", ebnum);
|
||||
@ -396,10 +395,10 @@ static int erasecrosstest(void)
|
||||
if (memcmp(writebuf, readbuf, pgsize)) {
|
||||
printk(PRINT_PREF "verify failed!\n");
|
||||
errcnt += 1;
|
||||
ok = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ok && !err)
|
||||
if (!err)
|
||||
printk(PRINT_PREF "erasecrosstest ok\n");
|
||||
return err;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,11 +2,12 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Created by Arjan van de Ven <arjanv@redhat.com>
|
||||
*
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
* Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
|
||||
* University of Szeged, Hungary
|
||||
*
|
||||
* Created by Arjan van de Ven <arjan@infradead.org>
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
*/
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
|
||||
* University of Szeged, Hungary
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in this directory.
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2007 Nokia Corporation. All rights reserved.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by Richard Purdie <rpurdie@openedhand.com>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by Arjan van de Ven <arjanv@redhat.com>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by Arjan van de Ven <arjanv@redhat.com>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -2,6 +2,7 @@
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -24,7 +24,6 @@
|
||||
#ifdef __ECOS
|
||||
#include "os-ecos.h"
|
||||
#else
|
||||
#include <linux/mtd/compatmac.h> /* For compatibility with older kernels */
|
||||
#include "os-linux.h"
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
/*
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright (C) 2001-2003 Red Hat, Inc.
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -4,12 +4,26 @@
|
||||
* NAND family Bad Block Management (BBM) header file
|
||||
* - Bad Block Table (BBT) implementation
|
||||
*
|
||||
* Copyright (c) 2005 Samsung Electronics
|
||||
* Copyright © 2005 Samsung Electronics
|
||||
* Kyungmin Park <kyungmin.park@samsung.com>
|
||||
*
|
||||
* Copyright (c) 2000-2005
|
||||
* Copyright © 2000-2005
|
||||
* Thomas Gleixner <tglx@linuxtronix.de>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef __LINUX_MTD_BBM_H
|
||||
#define __LINUX_MTD_BBM_H
|
||||
@ -82,6 +96,12 @@ struct nand_bbt_descr {
|
||||
#define NAND_BBT_SAVECONTENT 0x00002000
|
||||
/* Search good / bad pattern on the first and the second page */
|
||||
#define NAND_BBT_SCAN2NDPAGE 0x00004000
|
||||
/* Search good / bad pattern on the last page of the eraseblock */
|
||||
#define NAND_BBT_SCANLASTPAGE 0x00008000
|
||||
/* Chip stores bad block marker on BOTH 1st and 6th bytes of OOB */
|
||||
#define NAND_BBT_SCANBYTE1AND6 0x00100000
|
||||
/* The nand_bbt_descr was created dynamicaly and must be freed */
|
||||
#define NAND_BBT_DYNAMICSTRUCT 0x00200000
|
||||
|
||||
/* The maximum number of blocks to scan for a bbt */
|
||||
#define NAND_BBT_SCAN_MAXBLOCKS 4
|
||||
|
@ -1,7 +1,19 @@
|
||||
/*
|
||||
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
|
||||
* Copyright © 2003-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Interface to Linux block layer for MTD 'translation layers'.
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -1,6 +1,20 @@
|
||||
|
||||
/* Common Flash Interface structures
|
||||
* See http://support.intel.com/design/flash/technote/index.htm
|
||||
/*
|
||||
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org> et al.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MTD_CFI_H__
|
||||
|
@ -1,3 +1,22 @@
|
||||
/*
|
||||
* 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 <asm/byteorder.h>
|
||||
|
||||
#ifndef CONFIG_MTD_CFI_ADV_OPTIONS
|
||||
|
@ -1,10 +0,0 @@
|
||||
|
||||
#ifndef __LINUX_MTD_COMPATMAC_H__
|
||||
#define __LINUX_MTD_COMPATMAC_H__
|
||||
|
||||
/* Nothing to see here. We write 2.5-compatible code and this
|
||||
file makes it all OK in older kernels, but it's empty in _current_
|
||||
kernels. Include guard just to make GCC ignore it in future inclusions
|
||||
anyway... */
|
||||
|
||||
#endif /* __LINUX_MTD_COMPATMAC_H__ */
|
@ -1,9 +1,22 @@
|
||||
/*
|
||||
* MTD device concatenation layer definitions
|
||||
*
|
||||
* (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
|
||||
* Copyright © 2002 Robert Kaiser <rkaiser@sysgo.de>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* This code is GPL
|
||||
*/
|
||||
|
||||
#ifndef MTD_CONCAT_H
|
||||
|
@ -1,12 +1,25 @@
|
||||
/*
|
||||
* Linux driver for Disk-On-Chip devices
|
||||
*
|
||||
* Copyright (C) 1999 Machine Vision Holdings, Inc.
|
||||
* Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org>
|
||||
* Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
|
||||
* Copyright (C) 2002-2003 SnapGear Inc
|
||||
* Copyright © 1999 Machine Vision Holdings, Inc.
|
||||
* Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
* Copyright © 2002-2003 Greg Ungerer <gerg@snapgear.com>
|
||||
* Copyright © 2002-2003 SnapGear Inc
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Released under GPL
|
||||
*/
|
||||
|
||||
#ifndef __MTD_DOC2000_H__
|
||||
|
@ -1,10 +1,21 @@
|
||||
|
||||
/*
|
||||
* struct flchip definition
|
||||
* Copyright © 2000 Red Hat UK Limited
|
||||
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* Contains information about the location and state of a given flash device
|
||||
* 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
|
||||
*
|
||||
* (C) 2000 Red Hat. GPLd.
|
||||
*/
|
||||
|
||||
#ifndef __MTD_FLASHCHIP_H__
|
||||
@ -92,7 +103,7 @@ struct flchip {
|
||||
/* This is used to handle contention on write/erase operations
|
||||
between partitions of the same physical chip. */
|
||||
struct flchip_shared {
|
||||
spinlock_t lock;
|
||||
struct mutex lock;
|
||||
struct flchip *writing;
|
||||
struct flchip *erasing;
|
||||
};
|
||||
|
@ -1,6 +1,21 @@
|
||||
/*
|
||||
* (C) 2001, 2001 Red Hat, Inc.
|
||||
* GPL'd
|
||||
* Copyright © 2001 Red Hat UK Limited
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MTD_GEN_PROBE_H__
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org> et al.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/* Overhauled routines for dealing with different mmap regions of flash */
|
||||
|
||||
@ -9,7 +27,6 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <asm/system.h>
|
||||
|
@ -1,7 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
|
||||
* Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Released under GPL
|
||||
*/
|
||||
|
||||
#ifndef __MTD_MTD_H__
|
||||
@ -13,7 +26,6 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <mtd/mtd-abi.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
@ -216,6 +228,7 @@ struct mtd_info {
|
||||
/* Chip-supported device locking */
|
||||
int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
|
||||
int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
|
||||
int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
|
||||
|
||||
/* Power Management functions */
|
||||
int (*suspend) (struct mtd_info *mtd);
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* linux/include/linux/mtd/nand.h
|
||||
*
|
||||
* Copyright (c) 2000 David Woodhouse <dwmw2@infradead.org>
|
||||
* Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
* Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -181,8 +181,6 @@ typedef enum {
|
||||
#define NAND_NO_READRDY 0x00000100
|
||||
/* Chip does not allow subpage writes */
|
||||
#define NAND_NO_SUBPAGE_WRITE 0x00000200
|
||||
/* Chip stores bad block marker on the last page of the eraseblock */
|
||||
#define NAND_BB_LAST_PAGE 0x00000400
|
||||
|
||||
/* Device is one of 'new' xD cards that expose fake nand command set */
|
||||
#define NAND_BROKEN_XD 0x00000400
|
||||
|
@ -1,7 +1,9 @@
|
||||
/*
|
||||
* drivers/mtd/nand_ecc.h
|
||||
*
|
||||
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
|
||||
* Copyright (C) 2000-2010 Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* David Woodhouse <dwmw2@infradead.org>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user