Commit ba7cc09c authored by Linus Torvalds's avatar Linus Torvalds

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

* git://git.infradead.org/mtd-2.6: (21 commits)
  [MTD] [CHIPS] Remove MTD_OBSOLETE_CHIPS (jedec, amd_flash, sharp)
  [MTD] Delete allegedly obsolete "bank_size" field of mtd_info.
  [MTD] Remove unnecessary user space check from mtd.h.
  [MTD] [MAPS] Remove flash maps for no longer supported 405LP boards
  [MTD] [MAPS] Fix missing printk() parameter in physmap_of.c MTD driver
  [MTD] [NAND] platform NAND driver: add driver
  [MTD] [NAND] platform NAND driver: update header
  [JFFS2] Simplify and clean up jffs2_add_tn_to_tree() some more.
  [JFFS2] Remove another bogus optimisation in jffs2_add_tn_to_tree()
  [JFFS2] Remove broken insert_point optimisation in jffs2_add_tn_to_tree()
  [JFFS2] Remember to calculate overlap on nodes which replace older nodes
  [JFFS2] Don't advance c->wbuf_ofs to next eraseblock after wbuf flush
  [MTD] [NAND] at91_nand.c: CMDLINE_PARTS support
  [MTD] [NAND] Tidy up handling of page number in nand_block_bad()
  [MTD] block2mtd_paramline[] mustn't be __initdata
  [MTD] [NAND] Support multiple chips in CAFÉ driver
  [MTD] [NAND] Rename cafe.c to cafe_nand.c and remove the multi-obj magic
  [MTD] [NAND] Use rslib for CAFÉ ECC
  [RSLIB] Support non-canonical GF representations
  [JFFS2] Remove dead file histo_mips.h
  ...
parents d84c4124 b7aa48be
...@@ -2648,6 +2648,12 @@ M: corbet@lwn.net ...@@ -2648,6 +2648,12 @@ M: corbet@lwn.net
L: video4linux-list@redhat.com L: video4linux-list@redhat.com
S: Maintained S: Maintained
ONENAND FLASH DRIVER
P: Kyungmin Park
M: kyungmin.park@samsung.com
L: linux-mtd@lists.infradead.org
S: Maintained
ONSTREAM SCSI TAPE DRIVER ONSTREAM SCSI TAPE DRIVER
P: Willem Riede P: Willem Riede
M: osst@riede.org M: osst@riede.org
......
# drivers/mtd/chips/Kconfig # drivers/mtd/chips/Kconfig
# $Id: Kconfig,v 1.18 2005/11/07 11:14:22 gleixner Exp $
menu "RAM/ROM/Flash chip drivers" menu "RAM/ROM/Flash chip drivers"
depends on MTD!=n depends on MTD!=n
...@@ -231,45 +230,6 @@ config MTD_ABSENT ...@@ -231,45 +230,6 @@ config MTD_ABSENT
the system regardless of media presence. Device nodes created the system regardless of media presence. Device nodes created
with this driver will return -ENODEV upon access. with this driver will return -ENODEV upon access.
config MTD_OBSOLETE_CHIPS
bool "Older (theoretically obsoleted now) drivers for non-CFI chips"
help
This option does not enable any code directly, but will allow you to
select some other chip drivers which are now considered obsolete,
because the generic CONFIG_JEDECPROBE code above should now detect
the chips which are supported by these drivers, and allow the generic
CFI-compatible drivers to drive the chips. Say 'N' here unless you have
already tried the CONFIG_JEDECPROBE method and reported its failure
to the MTD mailing list at <linux-mtd@lists.infradead.org>
config MTD_AMDSTD
tristate "AMD compatible flash chip support (non-CFI)"
depends on MTD_OBSOLETE_CHIPS && BROKEN
help
This option enables support for flash chips using AMD-compatible
commands, including some which are not CFI-compatible and hence
cannot be used with the CONFIG_MTD_CFI_AMDSTD option.
It also works on AMD compatible chips that do conform to CFI.
config MTD_SHARP
tristate "pre-CFI Sharp chip support"
depends on MTD_OBSOLETE_CHIPS
help
This option enables support for flash chips using Sharp-compatible
commands, including some which are not CFI-compatible and hence
cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
config MTD_JEDEC
tristate "JEDEC device support"
depends on MTD_OBSOLETE_CHIPS && BROKEN
help
Enable older JEDEC flash interface devices for self
programming flash. It is commonly used in older AMD chips. It is
only called JEDEC because the JEDEC association
<http://www.jedec.org/> distributes the identification codes for the
chips.
config MTD_XIP config MTD_XIP
bool "XIP aware MTD support" bool "XIP aware MTD support"
depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP
......
# #
# linux/drivers/chips/Makefile # linux/drivers/chips/Makefile
# #
# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
obj-$(CONFIG_MTD) += chipreg.o obj-$(CONFIG_MTD) += chipreg.o
obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
obj-$(CONFIG_MTD_CFI) += cfi_probe.o obj-$(CONFIG_MTD_CFI) += cfi_probe.o
obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o
obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
obj-$(CONFIG_MTD_GEN_PROBE) += gen_probe.o obj-$(CONFIG_MTD_GEN_PROBE) += gen_probe.o
obj-$(CONFIG_MTD_JEDEC) += jedec.o
obj-$(CONFIG_MTD_JEDECPROBE) += jedec_probe.o obj-$(CONFIG_MTD_JEDECPROBE) += jedec_probe.o
obj-$(CONFIG_MTD_RAM) += map_ram.o obj-$(CONFIG_MTD_RAM) += map_ram.o
obj-$(CONFIG_MTD_ROM) += map_rom.o obj-$(CONFIG_MTD_ROM) += map_rom.o
obj-$(CONFIG_MTD_SHARP) += sharp.o
obj-$(CONFIG_MTD_ABSENT) += map_absent.o obj-$(CONFIG_MTD_ABSENT) += map_absent.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -373,7 +373,7 @@ static inline void kill_final_newline(char *str) ...@@ -373,7 +373,7 @@ static inline void kill_final_newline(char *str)
#ifndef MODULE #ifndef MODULE
static int block2mtd_init_called = 0; static int block2mtd_init_called = 0;
static __initdata char block2mtd_paramline[80 + 12]; /* 80 for device, 12 for erase size */ static char block2mtd_paramline[80 + 12]; /* 80 for device, 12 for erase size */
#endif #endif
......
...@@ -358,22 +358,6 @@ config MTD_CFI_FLAGADM ...@@ -358,22 +358,6 @@ config MTD_CFI_FLAGADM
Mapping for the Flaga digital module. If you don't have one, ignore Mapping for the Flaga digital module. If you don't have one, ignore
this setting. this setting.
config MTD_BEECH
tristate "CFI Flash device mapped on IBM 405LP Beech"
depends on MTD_CFI && BEECH
help
This enables access routines for the flash chips on the IBM
405LP Beech board. If you have one of these boards and would like
to use the flash chips on it, say 'Y'.
config MTD_ARCTIC
tristate "CFI Flash device mapped on IBM 405LP Arctic"
depends on MTD_CFI && ARCTIC2
help
This enables access routines for the flash chips on the IBM 405LP
Arctic board. If you have one of these boards and would like to
use the flash chips on it, say 'Y'.
config MTD_WALNUT config MTD_WALNUT
tristate "Flash device mapped on IBM 405GP Walnut" tristate "Flash device mapped on IBM 405GP Walnut"
depends on MTD_JEDECPROBE && WALNUT depends on MTD_JEDECPROBE && WALNUT
......
...@@ -58,8 +58,6 @@ obj-$(CONFIG_MTD_NETtel) += nettel.o ...@@ -58,8 +58,6 @@ obj-$(CONFIG_MTD_NETtel) += nettel.o
obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
obj-$(CONFIG_MTD_EBONY) += ebony.o obj-$(CONFIG_MTD_EBONY) += ebony.o
obj-$(CONFIG_MTD_OCOTEA) += ocotea.o obj-$(CONFIG_MTD_OCOTEA) += ocotea.o
obj-$(CONFIG_MTD_BEECH) += beech-mtd.o
obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o
obj-$(CONFIG_MTD_WALNUT) += walnut.o obj-$(CONFIG_MTD_WALNUT) += walnut.o
obj-$(CONFIG_MTD_H720X) += h720x-flash.o obj-$(CONFIG_MTD_H720X) += h720x-flash.o
obj-$(CONFIG_MTD_SBC8240) += sbc8240.o obj-$(CONFIG_MTD_SBC8240) += sbc8240.o
......
/*
* $Id: arctic-mtd.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
*
* drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
* IBM 405LP Arctic boards.
*
* 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
*
* Copyright (C) 2002, International Business Machines Corporation
* All Rights Reserved.
*
* Bishop Brock
* IBM Research, Austin Center for Low-Power Computing
* bcbrock@us.ibm.com
* March 2002
*
* modified for Arctic by,
* David Gibson
* IBM OzLabs, Canberra, Australia
* <arctic@gibson.dropbear.id.au>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include <asm/ibm4xx.h>
/*
* 0 : 0xFE00 0000 - 0xFEFF FFFF : Filesystem 1 (16MiB)
* 1 : 0xFF00 0000 - 0xFF4F FFFF : kernel (5.12MiB)
* 2 : 0xFF50 0000 - 0xFFF5 FFFF : Filesystem 2 (10.624MiB) (if non-XIP)
* 3 : 0xFFF6 0000 - 0xFFFF FFFF : PIBS Firmware (640KiB)
*/
#define FFS1_SIZE 0x01000000 /* 16MiB */
#define KERNEL_SIZE 0x00500000 /* 5.12MiB */
#define FFS2_SIZE 0x00a60000 /* 10.624MiB */
#define FIRMWARE_SIZE 0x000a0000 /* 640KiB */
#define NAME "Arctic Linux Flash"
#define PADDR SUBZERO_BOOTFLASH_PADDR
#define BUSWIDTH 2
#define SIZE SUBZERO_BOOTFLASH_SIZE
#define PARTITIONS 4
/* Flash memories on these boards are memory resources, accessed big-endian. */
{
/* do nothing for now */
}
static struct map_info arctic_mtd_map = {
.name = NAME,
.size = SIZE,
.bankwidth = BUSWIDTH,
.phys = PADDR,
};
static struct mtd_info *arctic_mtd;
static struct mtd_partition arctic_partitions[PARTITIONS] = {
{ .name = "Filesystem",
.size = FFS1_SIZE,
.offset = 0,},
{ .name = "Kernel",
.size = KERNEL_SIZE,
.offset = FFS1_SIZE,},
{ .name = "Filesystem",
.size = FFS2_SIZE,
.offset = FFS1_SIZE + KERNEL_SIZE,},
{ .name = "Firmware",
.size = FIRMWARE_SIZE,
.offset = SUBZERO_BOOTFLASH_SIZE - FIRMWARE_SIZE,},
};
static int __init
init_arctic_mtd(void)
{
int err;
printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
arctic_mtd_map.virt = ioremap(PADDR, SIZE);
if (!arctic_mtd_map.virt) {
printk("%s: failed to ioremap 0x%x\n", NAME, PADDR);
return -EIO;
}
simple_map_init(&arctic_mtd_map);
printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
if (!arctic_mtd) {
iounmap(arctic_mtd_map.virt);
return -ENXIO;
}
arctic_mtd->owner = THIS_MODULE;
err = add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
if (err) {
printk("%s: add_mtd_partitions failed\n", NAME);
iounmap(arctic_mtd_map.virt);
}
return err;
}
static void __exit
cleanup_arctic_mtd(void)
{
if (arctic_mtd) {
del_mtd_partitions(arctic_mtd);
map_destroy(arctic_mtd);
iounmap((void *) arctic_mtd_map.virt);
}
}
module_init(init_arctic_mtd);
module_exit(cleanup_arctic_mtd);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Gibson <arctic@gibson.dropbear.id.au>");
MODULE_DESCRIPTION("MTD map and partitions for IBM 405LP Arctic boards");
/*
* $Id: beech-mtd.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
*
* drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
* IBM 405LP Beech boards.
*
* 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
*
* Copyright (C) 2002, International Business Machines Corporation
* All Rights Reserved.
*
* Bishop Brock
* IBM Research, Austin Center for Low-Power Computing
* bcbrock@us.ibm.com
* March 2002
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include <asm/ibm4xx.h>
#define NAME "Beech Linux Flash"
#define PADDR BEECH_BIGFLASH_PADDR
#define SIZE BEECH_BIGFLASH_SIZE
#define BUSWIDTH 1
/* Flash memories on these boards are memory resources, accessed big-endian. */
static struct map_info beech_mtd_map = {
.name = NAME,
.size = SIZE,
.bankwidth = BUSWIDTH,
.phys = PADDR
};
static struct mtd_info *beech_mtd;
static struct mtd_partition beech_partitions[2] = {
{
.name = "Linux Kernel",
.size = BEECH_KERNEL_SIZE,
.offset = BEECH_KERNEL_OFFSET
}, {
.name = "Free Area",
.size = BEECH_FREE_AREA_SIZE,
.offset = BEECH_FREE_AREA_OFFSET
}
};
static int __init
init_beech_mtd(void)
{
int err;
printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
beech_mtd_map.virt = ioremap(PADDR, SIZE);
if (!beech_mtd_map.virt) {
printk("%s: failed to ioremap 0x%x\n", NAME, PADDR);
return -EIO;
}
simple_map_init(&beech_mtd_map);
printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
if (!beech_mtd) {
iounmap(beech_mtd_map.virt);
return -ENXIO;
}
beech_mtd->owner = THIS_MODULE;
err = add_mtd_partitions(beech_mtd, beech_partitions, 2);
if (err) {
printk("%s: add_mtd_partitions failed\n", NAME);
iounmap(beech_mtd_map.virt);
}
return err;
}
static void __exit
cleanup_beech_mtd(void)
{
if (beech_mtd) {
del_mtd_partitions(beech_mtd);
map_destroy(beech_mtd);
iounmap((void *) beech_mtd_map.virt);
}
}
module_init(init_beech_mtd);
module_exit(cleanup_beech_mtd);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bishop Brock <bcbrock@us.ibm.com>");
MODULE_DESCRIPTION("MTD map and partitions for IBM 405LP Beech boards");
...@@ -186,7 +186,7 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev ...@@ -186,7 +186,7 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev
else { else {
if (strcmp(of_probe, "ROM")) if (strcmp(of_probe, "ROM"))
dev_dbg(&dev->dev, "map_probe: don't know probe type " dev_dbg(&dev->dev, "map_probe: don't know probe type "
"'%s', mapping as rom\n"); "'%s', mapping as rom\n", of_probe);
info->mtd = do_map_probe("mtd_rom", &info->map); info->mtd = do_map_probe("mtd_rom", &info->map);
} }
if (info->mtd == NULL) { if (info->mtd == NULL) {
......
...@@ -347,7 +347,6 @@ int add_mtd_partitions(struct mtd_info *master, ...@@ -347,7 +347,6 @@ int add_mtd_partitions(struct mtd_info *master,
slave->mtd.subpage_sft = master->subpage_sft; slave->mtd.subpage_sft = master->subpage_sft;
slave->mtd.name = parts[i].name; slave->mtd.name = parts[i].name;
slave->mtd.bank_size = master->bank_size;
slave->mtd.owner = master->owner; slave->mtd.owner = master->owner;
slave->mtd.read = part_read; slave->mtd.read = part_read;
......
...@@ -234,6 +234,8 @@ config MTD_NAND_BASLER_EXCITE ...@@ -234,6 +234,8 @@ config MTD_NAND_BASLER_EXCITE
config MTD_NAND_CAFE config MTD_NAND_CAFE
tristate "NAND support for OLPC CAFÉ chip" tristate "NAND support for OLPC CAFÉ chip"
depends on PCI depends on PCI
select REED_SOLOMON
select REED_SOLOMON_DEC16
help help
Use NAND flash attached to the CAFÉ chip designed for the $100 Use NAND flash attached to the CAFÉ chip designed for the $100
laptop. laptop.
...@@ -270,4 +272,13 @@ config MTD_NAND_NANDSIM ...@@ -270,4 +272,13 @@ config MTD_NAND_NANDSIM
The simulator may simulate various NAND flash chips for the The simulator may simulate various NAND flash chips for the
MTD nand layer. MTD nand layer.
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
via platform_data.
endif # MTD_NAND endif # MTD_NAND
...@@ -26,6 +26,6 @@ obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o ...@@ -26,6 +26,6 @@ obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o
obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
nand-objs := nand_base.o nand_bbt.o nand-objs := nand_base.o nand_bbt.o
cafe_nand-objs := cafe.o cafe_ecc.o
...@@ -82,6 +82,10 @@ static void at91_nand_disable(struct at91_nand_host *host) ...@@ -82,6 +82,10 @@ static void at91_nand_disable(struct at91_nand_host *host)
at91_set_gpio_value(host->board->enable_pin, 1); at91_set_gpio_value(host->board->enable_pin, 1);
} }
#ifdef CONFIG_MTD_PARTITIONS
const char *part_probes[] = { "cmdlinepart", NULL };
#endif
/* /*
* Probe for the NAND device. * Probe for the NAND device.
*/ */
...@@ -151,6 +155,12 @@ static int __init at91_nand_probe(struct platform_device *pdev) ...@@ -151,6 +155,12 @@ static int __init at91_nand_probe(struct platform_device *pdev)
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
if (host->board->partition_info) if (host->board->partition_info)
partitions = host->board->partition_info(mtd->size, &num_partitions); partitions = host->board->partition_info(mtd->size, &num_partitions);
#ifdef CONFIG_MTD_CMDLINE_PARTS
else {
mtd->name = "at91_nand";
num_partitions = parse_mtd_partitions(mtd, part_probes, &partitions, 0);
}
#endif
if ((!partitions) || (num_partitions == 0)) { if ((!partitions) || (num_partitions == 0)) {
printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n");
......
This diff is collapsed.
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#undef DEBUG #undef DEBUG
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/rslib.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -46,13 +47,14 @@ ...@@ -46,13 +47,14 @@
#define CAFE_GLOBAL_IRQ_MASK 0x300c #define CAFE_GLOBAL_IRQ_MASK 0x300c
#define CAFE_NAND_RESET 0x3034 #define CAFE_NAND_RESET 0x3034
int cafe_correct_ecc(unsigned char *buf, /* Missing from the datasheet: bit 19 of CTRL1 sets CE0 vs. CE1 */
unsigned short *chk_syndrome_list); #define CTRL1_CHIPSELECT (1<<19)
struct cafe_priv { struct cafe_priv {
struct nand_chip nand; struct nand_chip nand;
struct pci_dev *pdev; struct pci_dev *pdev;
void __iomem *mmio; void __iomem *mmio;
struct rs_control *rs;
uint32_t ctl1; uint32_t ctl1;
uint32_t ctl2; uint32_t ctl2;
int datalen; int datalen;
...@@ -195,8 +197,8 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, ...@@ -195,8 +197,8 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
cafe->data_pos = cafe->datalen = 0; cafe->data_pos = cafe->datalen = 0;
/* Set command valid bit */ /* Set command valid bit, mask in the chip select bit */
ctl1 = 0x80000000 | command; ctl1 = 0x80000000 | command | (cafe->ctl1 & CTRL1_CHIPSELECT);
/* Set RD or WR bits as appropriate */ /* Set RD or WR bits as appropriate */
if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) { if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) {
...@@ -309,8 +311,16 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, ...@@ -309,8 +311,16 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
static void cafe_select_chip(struct mtd_info *mtd, int chipnr) static void cafe_select_chip(struct mtd_info *mtd, int chipnr)
{ {
//struct cafe_priv *cafe = mtd->priv; struct cafe_priv *cafe = mtd->priv;
// cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
/* Mask the appropriate bit into the stored value of ctl1
which will be used by cafe_nand_cmdfunc() */
if (chipnr)
cafe->ctl1 |= CTRL1_CHIPSELECT;
else
cafe->ctl1 &= ~CTRL1_CHIPSELECT;
} }
static int cafe_nand_interrupt(int irq, void *id) static int cafe_nand_interrupt(int irq, void *id)
...@@ -374,28 +384,66 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -374,28 +384,66 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
if (checkecc && cafe_readl(cafe, NAND_ECC_RESULT) & (1<<18)) { if (checkecc && cafe_readl(cafe, NAND_ECC_RESULT) & (1<<18)) {
unsigned short syn[8]; unsigned short syn[8], pat[4];
int i; int pos[4];
u8 *oob = chip->oob_poi;
int i, n;
for (i=0; i<8; i+=2) { for (i=0; i<8; i+=2) {
uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN01 + (i*2)); uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN01 + (i*2));
syn[i] = tmp & 0xfff; syn[i] = cafe->rs->index_of[tmp & 0xfff];
syn[i+1] = (tmp >> 16) & 0xfff; syn[i+1] = cafe->rs->index_of[(tmp >> 16) & 0xfff];
}
n = decode_rs16(cafe->rs, NULL, NULL, 1367, syn, 0, pos, 0,
pat);
for (i = 0; i < n; i++) {
int p = pos[i];
/* The 12-bit symbols are mapped to bytes here */
if (p > 1374) {
/* out of range */
n = -1374;
} else if (p == 0) {
/* high four bits do not correspond to data */
if (pat[i] > 0xff)
n = -2048;
else
buf[0] ^= pat[i];
} else if (p == 1365) {
buf[2047] ^= pat[i] >> 4;
oob[0] ^= pat[i] << 4;
} else if (p > 1365) {
if ((p & 1) == 1) {
oob[3*p/2 - 2048] ^= pat[i] >> 4;
oob[3*p/2 - 2047] ^= pat[i] << 4;
} else {
oob[3*p/2 - 2049] ^= pat[i] >> 8;
oob[3*p/2 - 2048] ^= pat[i];
}
} else if ((p & 1) == 1) {
buf[3*p/2] ^= pat[i] >> 4;
buf[3*p/2 + 1] ^= pat[i] << 4;
} else {
buf[3*p/2 - 1] ^= pat[i] >> 8;
buf[3*p/2] ^= pat[i];
}
} }
if ((i = cafe_correct_ecc(buf, syn)) < 0) { if (n < 0) {
dev_dbg(&cafe->pdev->dev, "Failed to correct ECC at %08x\n", dev_dbg(&cafe->pdev->dev, "Failed to correct ECC at %08x\n",
cafe_readl(cafe, NAND_ADDR2) * 2048); cafe_readl(cafe, NAND_ADDR2) * 2048);
for (i=0; i< 0x5c; i+=4) for (i = 0; i < 0x5c; i += 4)
printk("Register %x: %08x\n", i, readl(cafe->mmio + i)); printk("Register %x: %08x\n", i, readl(cafe->mmio + i));
mtd->ecc_stats.failed++; mtd->ecc_stats.failed++;
} else { } else {
dev_dbg(&cafe->pdev->dev, "Corrected %d symbol errors\n", i); dev_dbg(&cafe->pdev->dev, "Corrected %d symbol errors\n", n);
mtd->ecc_stats.corrected += i; mtd->ecc_stats.corrected += n;
} }
} }
return 0; return 0;
} }
...@@ -416,7 +464,7 @@ static uint8_t cafe_mirror_pattern_512[] = { 0xBC }; ...@@ -416,7 +464,7 @@ static uint8_t cafe_mirror_pattern_512[] = { 0xBC };
static struct nand_bbt_descr cafe_bbt_main_descr_2048 = { static struct nand_bbt_descr cafe_bbt_main_descr_2048 = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | NAND_BBT_2BIT | NAND_BBT_VERSION,
.offs = 14, .offs = 14,
.len = 4, .len = 4,
.veroffs = 18, .veroffs = 18,
...@@ -426,7 +474,7 @@ static struct nand_bbt_descr cafe_bbt_main_descr_2048 = { ...@@ -426,7 +474,7 @@ static struct nand_bbt_descr cafe_bbt_main_descr_2048 = {
static struct nand_bbt_descr cafe_bbt_mirror_descr_2048 = { static struct nand_bbt_descr cafe_bbt_mirror_descr_2048 = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | NAND_BBT_2BIT | NAND_BBT_VERSION,
.offs = 14, .offs = 14,
.len = 4, .len = 4,
.veroffs = 18, .veroffs = 18,
...@@ -442,7 +490,7 @@ static struct nand_ecclayout cafe_oobinfo_512 = { ...@@ -442,7 +490,7 @@ static struct nand_ecclayout cafe_oobinfo_512 = {
static struct nand_bbt_descr cafe_bbt_main_descr_512 = { static struct nand_bbt_descr cafe_bbt_main_descr_512 = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | NAND_BBT_2BIT | NAND_BBT_VERSION,
.offs = 14, .offs = 14,
.len = 1, .len = 1,
.veroffs = 15, .veroffs = 15,
...@@ -452,7 +500,7 @@ static struct nand_bbt_descr cafe_bbt_main_descr_512 = { ...@@ -452,7 +500,7 @@ static struct nand_bbt_descr cafe_bbt_main_descr_512 = {
static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = { static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | NAND_BBT_2BIT | NAND_BBT_VERSION,
.offs = 14, .offs = 14,
.len = 1, .len = 1,
.veroffs = 15, .veroffs = 15,
...@@ -525,6 +573,48 @@ static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) ...@@ -525,6 +573,48 @@ static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
return 0; return 0;
} }
/* F_2[X]/(X**6+X+1) */
static unsigned short __devinit gf64_mul(u8 a, u8 b)
{
u8 c;
unsigned int i;
c = 0;
for (i = 0; i < 6; i++) {
if (a & 1)
c ^= b;
a >>= 1;
b <<= 1;
if ((b & 0x40) != 0)
b ^= 0x43;
}
return c;
}
/* F_64[X]/(X**2+X+A**-1) with A the generator of F_64[X] */
static u16 __devinit gf4096_mul(u16 a, u16 b)
{
u8 ah, al, bh, bl, ch, cl;
ah = a >> 6;
al = a & 0x3f;
bh = b >> 6;
bl = b & 0x3f;
ch = gf64_mul(ah ^ al, bh ^ bl) ^ gf64_mul(al, bl);
cl = gf64_mul(gf64_mul(ah, bh), 0x21) ^ gf64_mul(al, bl);
return (ch << 6) ^ cl;
}
static int __devinit cafe_mul(int x)
{
if (x == 0)
return 1;
return gf4096_mul(x, 0xe01);
}
static int __devinit cafe_nand_probe(struct pci_dev *pdev, static int __devinit cafe_nand_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
...@@ -564,6 +654,12 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, ...@@ -564,6 +654,12 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
} }
cafe->nand.buffers = (void *)cafe->dmabuf + 2112; cafe->nand.buffers = (void *)cafe->dmabuf + 2112;
cafe->rs = init_rs_non_canonical(12, &cafe_mul, 0, 1, 8);
if (!cafe->rs) {
err = -ENOMEM;
goto out_ior;
}
cafe->nand.cmdfunc = cafe_nand_cmdfunc; cafe->nand.cmdfunc = cafe_nand_cmdfunc;
cafe->nand.dev_ready = cafe_device_ready; cafe->nand.dev_ready = cafe_device_ready;
cafe->nand.read_byte = cafe_read_byte; cafe->nand.read_byte = cafe_read_byte;
...@@ -646,7 +742,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, ...@@ -646,7 +742,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK)); cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK));
/* Scan to find existence of the device */ /* Scan to find existence of the device */
if (nand_scan_ident(mtd, 1)) { if (nand_scan_ident(mtd, 2)) {
err = -ENXIO; err = -ENXIO;
goto out_irq; goto out_irq;
} }
...@@ -713,6 +809,7 @@ static void __devexit cafe_nand_remove(struct pci_dev *pdev) ...@@ -713,6 +809,7 @@ static void __devexit cafe_nand_remove(struct pci_dev *pdev)
cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK);
free_irq(pdev->irq, mtd); free_irq(pdev->irq, mtd);
nand_release(mtd); nand_release(mtd);
free_rs(cafe->rs);
pci_iounmap(pdev, cafe->mmio); pci_iounmap(pdev, cafe->mmio);
dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr); dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr);
kfree(mtd); kfree(mtd);
......
This diff is collapsed.
This diff is collapsed.
#define BIT_DIVIDER_MIPS 1043
static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment