Commit 3e04767a authored by Linus Torvalds's avatar Linus Torvalds

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

* git://git.infradead.org/mtd-2.6:
  [MTD] Cleanup of 'ioremap balanced with iounmap for drivers/mtd subsystem'
  [MTD] fix nftl_write warning
  [MTD] fix printk warning
  [MTD ONENAND] Check OneNAND lock scheme & all block unlock command support
  [MTD ONENAND] Remove unused MTD_ONENAND_SYNC_READ configuration
  [MTD ONENAND] Fix OneNAND probe
  [MTD NAND] Provide prototype for newly-exported nand_wait_ready()
  [MTD] Remove #ifndef __KERNEL__ hack in <mtd/mtd-abi.h>
  [MTD NAND] Allow override of page read and write functions.
  [MTD NAND] Allocate chip->buffers separately to allow it to be overridden
  [MTD NAND] Split nand_scan() into two parts; allow board driver to intervene
  [MTD NAND] Export nand_wait_ready() for use by board drivers
parents a12f66fc 76a5027c
...@@ -96,7 +96,7 @@ static struct mtd_partition arctic_partitions[PARTITIONS] = { ...@@ -96,7 +96,7 @@ static struct mtd_partition arctic_partitions[PARTITIONS] = {
static int __init static int __init
init_arctic_mtd(void) init_arctic_mtd(void)
{ {
int err = 0; int err;
printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR); printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
...@@ -112,7 +112,7 @@ init_arctic_mtd(void) ...@@ -112,7 +112,7 @@ init_arctic_mtd(void)
arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map); arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
if (!arctic_mtd) { if (!arctic_mtd) {
iounmap((void *) arctic_mtd_map.virt); iounmap(arctic_mtd_map.virt);
return -ENXIO; return -ENXIO;
} }
...@@ -121,7 +121,7 @@ init_arctic_mtd(void) ...@@ -121,7 +121,7 @@ init_arctic_mtd(void)
err = add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS); err = add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
if (err) { if (err) {
printk("%s: add_mtd_partitions failed\n", NAME); printk("%s: add_mtd_partitions failed\n", NAME);
iounmap((void *) arctic_mtd_map.virt); iounmap(arctic_mtd_map.virt);
} }
return err; return err;
......
...@@ -72,7 +72,7 @@ static struct mtd_partition beech_partitions[2] = { ...@@ -72,7 +72,7 @@ static struct mtd_partition beech_partitions[2] = {
static int __init static int __init
init_beech_mtd(void) init_beech_mtd(void)
{ {
int err = 0; int err;
printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR); printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
...@@ -89,7 +89,7 @@ init_beech_mtd(void) ...@@ -89,7 +89,7 @@ init_beech_mtd(void)
beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map); beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
if (!beech_mtd) { if (!beech_mtd) {
iounmap((void *) beech_mtd_map.virt); iounmap(beech_mtd_map.virt);
return -ENXIO; return -ENXIO;
} }
...@@ -98,7 +98,7 @@ init_beech_mtd(void) ...@@ -98,7 +98,7 @@ init_beech_mtd(void)
err = add_mtd_partitions(beech_mtd, beech_partitions, 2); err = add_mtd_partitions(beech_mtd, beech_partitions, 2);
if (err) { if (err) {
printk("%s: add_mtd_partitions failed\n", NAME); printk("%s: add_mtd_partitions failed\n", NAME);
iounmap((void *) beech_mtd_map.virt); iounmap(beech_mtd_map.virt);
} }
return err; return err;
......
...@@ -175,8 +175,8 @@ int __init init_cstm_mips_ixx(void) ...@@ -175,8 +175,8 @@ int __init init_cstm_mips_ixx(void)
printk(KERN_WARNING "Failed to ioremap\n"); printk(KERN_WARNING "Failed to ioremap\n");
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
if (cstm_mips_ixx_map[j].virt) { if (cstm_mips_ixx_map[j].virt) {
iounmap((void *)cstm_mips_ixx_map[j].virt); iounmap(cstm_mips_ixx_map[j].virt);
cstm_mips_ixx_map[j].virt = 0; cstm_mips_ixx_map[j].virt = NULL;
} }
} }
return -EIO; return -EIO;
...@@ -214,8 +214,8 @@ int __init init_cstm_mips_ixx(void) ...@@ -214,8 +214,8 @@ int __init init_cstm_mips_ixx(void)
else { else {
for (i = 0; i < PHYSMAP_NUMBER; i++) { for (i = 0; i < PHYSMAP_NUMBER; i++) {
if (cstm_mips_ixx_map[i].virt) { if (cstm_mips_ixx_map[i].virt) {
iounmap((void *)cstm_mips_ixx_map[i].virt); iounmap(cstm_mips_ixx_map[i].virt);
cstm_mips_ixx_map[i].virt = 0; cstm_mips_ixx_map[i].virt = NULL;
} }
} }
return -ENXIO; return -ENXIO;
......
...@@ -463,7 +463,7 @@ int __init nettel_init(void) ...@@ -463,7 +463,7 @@ int __init nettel_init(void)
#ifdef CONFIG_MTD_CFI_INTELEXT #ifdef CONFIG_MTD_CFI_INTELEXT
out_unmap1: out_unmap1:
iounmap((void *) nettel_intel_map.virt); iounmap(nettel_intel_map.virt);
#endif #endif
out_unmap2: out_unmap2:
......
...@@ -126,7 +126,7 @@ static struct mtd_info *redwood_mtd; ...@@ -126,7 +126,7 @@ static struct mtd_info *redwood_mtd;
int __init init_redwood_flash(void) int __init init_redwood_flash(void)
{ {
int err = 0; int err;
printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n", printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
WINDOW_SIZE, WINDOW_ADDR); WINDOW_SIZE, WINDOW_ADDR);
......
...@@ -69,7 +69,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, ...@@ -69,7 +69,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
return 1; return 1;
default: default:
printk(KERN_NOTICE "Unknown request %ld\n", rq_data_dir(req)); printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
return 0; return 0;
} }
} }
......
...@@ -199,7 +199,7 @@ static void __exit ep7312_cleanup(void) ...@@ -199,7 +199,7 @@ static void __exit ep7312_cleanup(void)
nand_release(ap7312_mtd); nand_release(ap7312_mtd);
/* Release io resource */ /* Release io resource */
iounmap((void *)this->IO_ADDR_R); iounmap(this->IO_ADDR_R);
/* Free the MTD device structure */ /* Free the MTD device structure */
kfree(ep7312_mtd); kfree(ep7312_mtd);
......
This diff is collapsed.
...@@ -759,7 +759,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b ...@@ -759,7 +759,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
bd->options &= ~NAND_BBT_SCANEMPTY; bd->options &= ~NAND_BBT_SCANEMPTY;
return create_bbt(mtd, this->buffers.databuf, bd, -1); return create_bbt(mtd, this->buffers->databuf, bd, -1);
} }
/** /**
......
...@@ -175,6 +175,8 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len, ...@@ -175,6 +175,8 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
return res; return res;
} }
#ifdef CONFIG_NFTL_RW
/* /*
* Write data and oob to flash * Write data and oob to flash
*/ */
...@@ -196,8 +198,6 @@ static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len, ...@@ -196,8 +198,6 @@ static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
return res; return res;
} }
#ifdef CONFIG_NFTL_RW
/* Actual NFTL access routines */ /* Actual NFTL access routines */
/* NFTL_findfreeblock: Find a free Erase Unit on the NFTL partition. This function is used /* NFTL_findfreeblock: Find a free Erase Unit on the NFTL partition. This function is used
* when the give Virtual Unit Chain * when the give Virtual Unit Chain
......
...@@ -43,10 +43,4 @@ config MTD_ONENAND_OTP ...@@ -43,10 +43,4 @@ config MTD_ONENAND_OTP
OTP block is fully-guaranteed to be a valid block. OTP block is fully-guaranteed to be a valid block.
config MTD_ONENAND_SYNC_READ
bool "OneNAND Sync. Burst Read Support"
depends on ARCH_OMAP
help
This enables support for Sync. Burst Read.
endmenu endmenu
/* /*
* linux/drivers/mtd/onenand/onenand_base.c * linux/drivers/mtd/onenand/onenand_base.c
* *
* Copyright (C) 2005 Samsung Electronics * Copyright (C) 2005-2006 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com> * Kyungmin Park <kyungmin.park@samsung.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -199,6 +199,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le ...@@ -199,6 +199,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
case ONENAND_CMD_UNLOCK: case ONENAND_CMD_UNLOCK:
case ONENAND_CMD_LOCK: case ONENAND_CMD_LOCK:
case ONENAND_CMD_LOCK_TIGHT: case ONENAND_CMD_LOCK_TIGHT:
case ONENAND_CMD_UNLOCK_ALL:
block = -1; block = -1;
page = -1; page = -1;
break; break;
...@@ -1211,11 +1212,11 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) ...@@ -1211,11 +1212,11 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
end = len >> this->erase_shift; end = len >> this->erase_shift;
/* Continuous lock scheme */ /* Continuous lock scheme */
if (this->options & ONENAND_CONT_LOCK) { if (this->options & ONENAND_HAS_CONT_LOCK) {
/* Set start block address */ /* Set start block address */
this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS); this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
/* Set end block address */ /* Set end block address */
this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS); this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
/* Write unlock command */ /* Write unlock command */
this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0); this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
...@@ -1236,7 +1237,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) ...@@ -1236,7 +1237,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
} }
/* Block lock scheme */ /* Block lock scheme */
for (block = start; block < end; block++) { for (block = start; block < start + end; block++) {
/* Set block address */ /* Set block address */
value = onenand_block_address(this, block); value = onenand_block_address(this, block);
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
...@@ -1265,6 +1266,79 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) ...@@ -1265,6 +1266,79 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
return 0; return 0;
} }
/**
* onenand_check_lock_status - [OneNAND Interface] Check lock status
* @param this onenand chip data structure
*
* Check lock status
*/
static void onenand_check_lock_status(struct onenand_chip *this)
{
unsigned int value, block, status;
unsigned int end;
end = this->chipsize >> this->erase_shift;
for (block = 0; block < end; block++) {
/* Set block address */
value = onenand_block_address(this, block);
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
/* Select DataRAM for DDP */
value = onenand_bufferram_address(this, block);
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
/* Set start block address */
this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
/* Check lock status */
status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
if (!(status & ONENAND_WP_US))
printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
}
}
/**
* onenand_unlock_all - [OneNAND Interface] unlock all blocks
* @param mtd MTD device structure
*
* Unlock all blocks
*/
static int onenand_unlock_all(struct mtd_info *mtd)
{
struct onenand_chip *this = mtd->priv;
if (this->options & ONENAND_HAS_UNLOCK_ALL) {
/* Write unlock command */
this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
/* There's no return value */
this->wait(mtd, FL_UNLOCKING);
/* Sanity check */
while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
& ONENAND_CTRL_ONGO)
continue;
/* Workaround for all block unlock in DDP */
if (this->device_id & ONENAND_DEVICE_IS_DDP) {
loff_t ofs;
size_t len;
/* 1st block on another chip */
ofs = this->chipsize >> 1;
len = 1 << this->erase_shift;
onenand_unlock(mtd, ofs, len);
}
onenand_check_lock_status(this);
return 0;
}
mtd->unlock(mtd, 0x0, this->chipsize);
return 0;
}
#ifdef CONFIG_MTD_ONENAND_OTP #ifdef CONFIG_MTD_ONENAND_OTP
/* Interal OTP operation */ /* Interal OTP operation */
...@@ -1563,13 +1637,44 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, ...@@ -1563,13 +1637,44 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
} }
#endif /* CONFIG_MTD_ONENAND_OTP */ #endif /* CONFIG_MTD_ONENAND_OTP */
/**
* onenand_lock_scheme - Check and set OneNAND lock scheme
* @param mtd MTD data structure
*
* Check and set OneNAND lock scheme
*/
static void onenand_lock_scheme(struct mtd_info *mtd)
{
struct onenand_chip *this = mtd->priv;
unsigned int density, process;
/* Lock scheme depends on density and process */
density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
/* Lock scheme */
if (density >= ONENAND_DEVICE_DENSITY_1Gb) {
/* A-Die has all block unlock */
if (process) {
printk(KERN_DEBUG "Chip support all block unlock\n");
this->options |= ONENAND_HAS_UNLOCK_ALL;
}
} else {
/* Some OneNAND has continues lock scheme */
if (!process) {
printk(KERN_DEBUG "Lock scheme is Continues Lock\n");
this->options |= ONENAND_HAS_CONT_LOCK;
}
}
}
/** /**
* onenand_print_device_info - Print device ID * onenand_print_device_info - Print device ID
* @param device device ID * @param device device ID
* *
* Print device ID * Print device ID
*/ */
static void onenand_print_device_info(int device) static void onenand_print_device_info(int device, int version)
{ {
int vcc, demuxed, ddp, density; int vcc, demuxed, ddp, density;
...@@ -1583,6 +1688,7 @@ static void onenand_print_device_info(int device) ...@@ -1583,6 +1688,7 @@ static void onenand_print_device_info(int device)
(16 << density), (16 << density),
vcc ? "2.65/3.3" : "1.8", vcc ? "2.65/3.3" : "1.8",
device); device);
printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version);
} }
static const struct onenand_manufacturers onenand_manuf_ids[] = { static const struct onenand_manufacturers onenand_manuf_ids[] = {
...@@ -1625,9 +1731,14 @@ static int onenand_check_maf(int manuf) ...@@ -1625,9 +1731,14 @@ static int onenand_check_maf(int manuf)
static int onenand_probe(struct mtd_info *mtd) static int onenand_probe(struct mtd_info *mtd)
{ {
struct onenand_chip *this = mtd->priv; struct onenand_chip *this = mtd->priv;
int bram_maf_id, bram_dev_id, maf_id, dev_id; int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
int version_id;
int density; int density;
int syscfg;
/* Save system configuration 1 */
syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
/* Clear Sync. Burst Read mode to read BootRAM */
this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1);
/* Send the command for reading device ID from BootRAM */ /* Send the command for reading device ID from BootRAM */
this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM); this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
...@@ -1636,24 +1747,31 @@ static int onenand_probe(struct mtd_info *mtd) ...@@ -1636,24 +1747,31 @@ static int onenand_probe(struct mtd_info *mtd)
bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0); bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2); bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
/* Reset OneNAND to read default register values */
this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
/* Wait reset */
this->wait(mtd, FL_RESETING);
/* Restore system configuration 1 */
this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
/* Check manufacturer ID */ /* Check manufacturer ID */
if (onenand_check_maf(bram_maf_id)) if (onenand_check_maf(bram_maf_id))
return -ENXIO; return -ENXIO;
/* Reset OneNAND to read default register values */
this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
/* Read manufacturer and device IDs from Register */ /* Read manufacturer and device IDs from Register */
maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
ver_id= this->read_word(this->base + ONENAND_REG_VERSION_ID);
/* Check OneNAND device */ /* Check OneNAND device */
if (maf_id != bram_maf_id || dev_id != bram_dev_id) if (maf_id != bram_maf_id || dev_id != bram_dev_id)
return -ENXIO; return -ENXIO;
/* Flash device information */ /* Flash device information */
onenand_print_device_info(dev_id); onenand_print_device_info(dev_id, ver_id);
this->device_id = dev_id; this->device_id = dev_id;
this->version_id = ver_id;
density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
this->chipsize = (16 << density) << 20; this->chipsize = (16 << density) << 20;
...@@ -1676,16 +1794,8 @@ static int onenand_probe(struct mtd_info *mtd) ...@@ -1676,16 +1794,8 @@ static int onenand_probe(struct mtd_info *mtd)
mtd->size = this->chipsize; mtd->size = this->chipsize;
/* Version ID */ /* Check OneNAND lock scheme */
version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID); onenand_lock_scheme(mtd);
printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
/* Lock scheme */
if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
!(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
printk(KERN_INFO "Lock scheme is Continues Lock\n");
this->options |= ONENAND_CONT_LOCK;
}
return 0; return 0;
} }
...@@ -1821,7 +1931,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) ...@@ -1821,7 +1931,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
mtd->owner = THIS_MODULE; mtd->owner = THIS_MODULE;
/* Unlock whole block */ /* Unlock whole block */
mtd->unlock(mtd, 0x0, this->chipsize); onenand_unlock_all(mtd);
return this->scan_bbt(mtd); return this->scan_bbt(mtd);
} }
......
...@@ -27,9 +27,17 @@ ...@@ -27,9 +27,17 @@
struct mtd_info; struct mtd_info;
/* Scan and identify a NAND device */ /* Scan and identify a NAND device */
extern int nand_scan (struct mtd_info *mtd, int max_chips); extern int nand_scan (struct mtd_info *mtd, int max_chips);
/* Separate phases of nand_scan(), allowing board driver to intervene
* and override command or ECC setup according to flash type */
extern int nand_scan_ident(struct mtd_info *mtd, int max_chips);
extern int nand_scan_tail(struct mtd_info *mtd);
/* Free resources held by the NAND device */ /* Free resources held by the NAND device */
extern void nand_release (struct mtd_info *mtd); extern void nand_release (struct mtd_info *mtd);
/* Internal helper for board drivers which need to override command function */
extern void nand_wait_ready(struct mtd_info *mtd);
/* The maximum number of NAND chips in an array */ /* The maximum number of NAND chips in an array */
#define NAND_MAX_CHIPS 8 #define NAND_MAX_CHIPS 8
...@@ -178,7 +186,9 @@ typedef enum { ...@@ -178,7 +186,9 @@ typedef enum {
#define NAND_USE_FLASH_BBT 0x00010000 #define NAND_USE_FLASH_BBT 0x00010000
/* This option skips the bbt scan during initialization. */ /* This option skips the bbt scan during initialization. */
#define NAND_SKIP_BBTSCAN 0x00020000 #define NAND_SKIP_BBTSCAN 0x00020000
/* This option is defined if the board driver allocates its own buffers
(e.g. because it needs them DMA-coherent */
#define NAND_OWN_BUFFERS 0x00040000
/* Options set by nand scan */ /* Options set by nand scan */
/* Nand scan has allocated controller struct */ /* Nand scan has allocated controller struct */
#define NAND_CONTROLLER_ALLOC 0x80000000 #define NAND_CONTROLLER_ALLOC 0x80000000
...@@ -228,6 +238,8 @@ struct nand_hw_control { ...@@ -228,6 +238,8 @@ struct nand_hw_control {
* be provided if an hardware ECC is available * be provided if an hardware ECC is available
* @calculate: function for ecc calculation or readback from ecc hardware * @calculate: function for ecc calculation or readback from ecc hardware
* @correct: function for ecc correction, matching to ecc generator (sw/hw) * @correct: function for ecc correction, matching to ecc generator (sw/hw)
* @read_page_raw: function to read a raw page without ECC
* @write_page_raw: function to write a raw page without ECC
* @read_page: function to read a page according to the ecc generator requirements * @read_page: function to read a page according to the ecc generator requirements
* @write_page: function to write a page according to the ecc generator requirements * @write_page: function to write a page according to the ecc generator requirements
* @read_oob: function to read chip OOB data * @read_oob: function to read chip OOB data
...@@ -249,6 +261,12 @@ struct nand_ecc_ctrl { ...@@ -249,6 +261,12 @@ struct nand_ecc_ctrl {
int (*correct)(struct mtd_info *mtd, uint8_t *dat, int (*correct)(struct mtd_info *mtd, uint8_t *dat,
uint8_t *read_ecc, uint8_t *read_ecc,
uint8_t *calc_ecc); uint8_t *calc_ecc);
int (*read_page_raw)(struct mtd_info *mtd,
struct nand_chip *chip,
uint8_t *buf);
void (*write_page_raw)(struct mtd_info *mtd,
struct nand_chip *chip,
const uint8_t *buf);
int (*read_page)(struct mtd_info *mtd, int (*read_page)(struct mtd_info *mtd,
struct nand_chip *chip, struct nand_chip *chip,
uint8_t *buf); uint8_t *buf);
...@@ -337,6 +355,7 @@ struct nand_buffers { ...@@ -337,6 +355,7 @@ struct nand_buffers {
* @priv: [OPTIONAL] pointer to private chip date * @priv: [OPTIONAL] pointer to private chip date
* @errstat: [OPTIONAL] hardware specific function to perform additional error status checks * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
* (determine if errors are correctable) * (determine if errors are correctable)
* @write_page [REPLACEABLE] High-level page write function
*/ */
struct nand_chip { struct nand_chip {
...@@ -359,6 +378,8 @@ struct nand_chip { ...@@ -359,6 +378,8 @@ struct nand_chip {
void (*erase_cmd)(struct mtd_info *mtd, int page); void (*erase_cmd)(struct mtd_info *mtd, int page);
int (*scan_bbt)(struct mtd_info *mtd); int (*scan_bbt)(struct mtd_info *mtd);
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page); int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int page, int cached, int raw);
int chip_delay; int chip_delay;
unsigned int options; unsigned int options;
...@@ -380,7 +401,7 @@ struct nand_chip { ...@@ -380,7 +401,7 @@ struct nand_chip {
struct nand_ecclayout *ecclayout; struct nand_ecclayout *ecclayout;
struct nand_ecc_ctrl ecc; struct nand_ecc_ctrl ecc;
struct nand_buffers buffers; struct nand_buffers *buffers;
struct nand_hw_control hwcontrol; struct nand_hw_control hwcontrol;
struct mtd_oob_ops ops; struct mtd_oob_ops ops;
......
/* /*
* linux/include/linux/mtd/onenand.h * linux/include/linux/mtd/onenand.h
* *
* Copyright (C) 2005 Samsung Electronics * Copyright (C) 2005-2006 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com> * Kyungmin Park <kyungmin.park@samsung.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -96,6 +96,7 @@ struct onenand_chip { ...@@ -96,6 +96,7 @@ struct onenand_chip {
void __iomem *base; void __iomem *base;
unsigned int chipsize; unsigned int chipsize;
unsigned int device_id; unsigned int device_id;
unsigned int version_id;
unsigned int density_mask; unsigned int density_mask;
unsigned int options; unsigned int options;
...@@ -149,7 +150,8 @@ struct onenand_chip { ...@@ -149,7 +150,8 @@ struct onenand_chip {
/* /*
* Options bits * Options bits
*/ */
#define ONENAND_CONT_LOCK (0x0001) #define ONENAND_HAS_CONT_LOCK (0x0001)
#define ONENAND_HAS_UNLOCK_ALL (0x0002)
#define ONENAND_PAGEBUF_ALLOC (0x1000) #define ONENAND_PAGEBUF_ALLOC (0x1000)
/* /*
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* OneNAND Register header file * OneNAND Register header file
* *
* Copyright (C) 2005 Samsung Electronics * Copyright (C) 2005-2006 Samsung Electronics
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
#define ONENAND_DEVICE_VCC_MASK (0x3) #define ONENAND_DEVICE_VCC_MASK (0x3)
#define ONENAND_DEVICE_DENSITY_512Mb (0x002) #define ONENAND_DEVICE_DENSITY_512Mb (0x002)
#define ONENAND_DEVICE_DENSITY_1Gb (0x003)
/* /*
* Version ID Register F002h (R) * Version ID Register F002h (R)
...@@ -110,6 +111,7 @@ ...@@ -110,6 +111,7 @@
#define ONENAND_CMD_UNLOCK (0x23) #define ONENAND_CMD_UNLOCK (0x23)
#define ONENAND_CMD_LOCK (0x2A) #define ONENAND_CMD_LOCK (0x2A)
#define ONENAND_CMD_LOCK_TIGHT (0x2C) #define ONENAND_CMD_LOCK_TIGHT (0x2C)
#define ONENAND_CMD_UNLOCK_ALL (0x27)
#define ONENAND_CMD_ERASE (0x94) #define ONENAND_CMD_ERASE (0x94)
#define ONENAND_CMD_RESET (0xF0) #define ONENAND_CMD_RESET (0xF0)
#define ONENAND_CMD_OTP_ACCESS (0x65) #define ONENAND_CMD_OTP_ACCESS (0x65)
......
header-y += inftl-user.h header-y += inftl-user.h
header-y += jffs2-user.h header-y += jffs2-user.h
header-y += mtd-abi.h
header-y += mtd-user.h header-y += mtd-user.h
header-y += nftl-user.h header-y += nftl-user.h
unifdef-y += mtd-abi.h
...@@ -7,12 +7,6 @@ ...@@ -7,12 +7,6 @@
#ifndef __MTD_ABI_H__ #ifndef __MTD_ABI_H__
#define __MTD_ABI_H__ #define __MTD_ABI_H__
#ifndef __KERNEL__
/* Urgh. The whole point of splitting this out into
separate files was to avoid #ifdef __KERNEL__ */
#define __user
#endif
struct erase_info_user { struct erase_info_user {
uint32_t start; uint32_t start;
uint32_t length; uint32_t length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment