[
  [
    "linux-2.6.23.orig/drivers/mtd/nand/Kconfig", 
    "linux-2.6.23/drivers/mtd/nand/Kconfig", 
    [
      "Index: linux-2.6.23/drivers/mtd/nand/Kconfig", 
      "===================================================================", 
      "--- linux-2.6.23.orig/drivers/mtd/nand/Kconfig", 
      "+++ linux-2.6.23/drivers/mtd/nand/Kconfig", 
      "@@ -264,6 +264,11 @@ config MTD_NAND_CM_X270", 
      "tristate \"Support for NAND Flash on CM-X270 modules\"", 
      "depends on MTD_NAND && MACH_ARMCORE", 
      "", 
      "+config MTD_NAND_VIP19XX", 
      "+       tristate \"Support for NAND flash device on Motorola VIP19xx boards\"", 
      "+       depends on SH_MOTOROLA_VIP19XX && MTD_NAND", 
      "+       help", 
      "+         Driver for the NAND flash on Motorola VIP19xx boards.", 
      "", 
      "config MTD_NAND_NANDSIM", 
      "tristate \"Support for NAND Flash Simulator\""
    ]
  ], 
  [
    "linux-2.6.23.orig/drivers/mtd/nand/Makefile", 
    "linux-2.6.23/drivers/mtd/nand/Makefile", 
    [
      "Index: linux-2.6.23/drivers/mtd/nand/Makefile", 
      "===================================================================", 
      "--- linux-2.6.23.orig/drivers/mtd/nand/Makefile", 
      "+++ linux-2.6.23/drivers/mtd/nand/Makefile", 
      "@@ -27,6 +27,7 @@ obj-$(CONFIG_MTD_NAND_AT91)\t\t+= at91_nan", 
      "obj-$(CONFIG_MTD_NAND_CM_X270)\t\t+= cmx270_nand.o", 
      "obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)\t+= excite_nandflash.o", 
      "obj-$(CONFIG_MTD_NAND_PLATFORM)\t\t+= plat_nand.o", 
      "+obj-$(CONFIG_MTD_NAND_VIP19XX)\t\t+= vip19xx_nand.o", 
      "obj-$(CONFIG_MTD_NAND_STM_EMI)\t\t+= stm_nand_emi.o", 
      "obj-$(CONFIG_MTD_NAND_STM_FLEX)\t\t+= stm_nand_flex.o stm_nand_ecc.o", 
      ""
    ]
  ], 
  [
    "dev/null", 
    "linux-2.6.23/drivers/mtd/nand/vip19xx_nand.c", 
    [
      "Index: linux-2.6.23/drivers/mtd/nand/vip19xx_nand.c", 
      "===================================================================", 
      "--- dev/null", 
      "+++ linux-2.6.23/drivers/mtd/nand/vip19xx_nand.c", 
      "@@ -0,0 +1,333 @@", 
      "+/*", 
      "+ *---------------------------------------------------------------------------", 
      "+ *", 
      "+ * vip19xx_nand.c", 
      "+ *", 
      "+ * Copyright (c) 2008-2011 Motorola, Inc.", 
      "+ * All rights reserved.", 
      "+ *", 
      "+ * Redistribution and use in source and binary forms, with or without", 
      "+ * modification, are permitted provided that the following conditions", 
      "+ * are met:", 
      "+ * 1. Redistributions of source code must retain the above copyright", 
      "+ * notice, this list of conditions and the following disclaimer.", 
      "+ * 2. Redistributions in binary form must reproduce the above copyright", 
      "+ * notice, this list of conditions and the following disclaimer in the", 
      "+ * documentation and/or other materials provided with the distribution.", 
      "+ * 3. The name of the author may not be used to endorse or promote products", 
      "+ * derived from this software without specific prior written permission.", 
      "+ *", 
      "+ * Alternatively, this software may be distributed under the terms of the", 
      "+ * GNU General Public License (\"GPL\") version 2 as published by the Free", 
      "+ * Software Foundation.", 
      "+ *", 
      "+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR", 
      "+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES", 
      "+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.", 
      "+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,", 
      "+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT", 
      "+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,", 
      "+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY", 
      "+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT", 
      "+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF", 
      "+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", 
      "+ *", 
      "+ *---------------------------------------------------------------------------", 
      "+ */", 
      "+", 
      "+#include <linux/kernel.h>", 
      "+#include <linux/init.h>", 
      "+#include <linux/slab.h>", 
      "+#include <linux/module.h>", 
      "+#include <linux/mtd/mtd.h>", 
      "+#include <linux/mtd/nand.h>", 
      "+#include <linux/mtd/partitions.h>", 
      "+#include <asm/io.h>", 
      "+#include <asm/vip19xx.h>", 
      "+", 
      "+#include <linux/stm/pio.h>", 
      "+", 
      "+#define NAME \"vip19xx_nand\"", 
      "+", 
      "+static struct mtd_info *nand_mtd = NULL;", 
      "+static int nand_cs = 0;", 
      "+", 
      "+/* PIO structs */", 
      "+static struct stpio_pin *nand_cle = NULL;", 
      "+static struct stpio_pin *nand_ale = NULL;", 
      "+static struct stpio_pin *nand_rbusy = NULL;", 
      "+", 
      "+static int nand_port = 2;", 
      "+static int cle_pin = 2;", 
      "+static int ale_pin = 3;", 
      "+static int rbusy_pin = 5;", 
      "+", 
      "+DECLARE_WAIT_QUEUE_HEAD(rbusy_wait);", 
      "+", 
      "+/*", 
      "+ * Define partitions for flash device", 
      "+ */", 
      "+static struct mtd_partition partition_info[] = {", 
      "+\t{", 
      "+\t\t.name\t= \"VIP19xx NANDflash partition\",", 
      "+\t\t.offset\t= 0,", 
      "+\t\t.size\t= 32 * 1024 * 1024", 
      "+\t}", 
      "+};", 
      "+", 
      "+static inline u16 WriteConversion(uint8_t data)", 
      "+{", 
      "+\treturn", 
      "+\t\t((data & 0x01)<<9) | // bit 0", 
      "+\t\t((data & 0x02)<<1) | // bit 1", 
      "+\t\t((data & 0x14)<<8) | // bit 2, 4", 
      "+\t\t (data & 0x28)     | // bit 3, 5", 
      "+\t\t((data & 0x40)<<7) | // bit 6", 
      "+\t\t((data & 0x80)>>1);", 
      "+}", 
      "+", 
      "+static inline uint8_t ReadConversion(u16 data)", 
      "+{", 
      "+\treturn", 
      "+\t\t((data & 0x0200)>>9) | // bit 0", 
      "+\t\t((data & 0x0004)>>1) | // bit 1", 
      "+\t\t((data & 0x1400)>>8) | // bit 2, 4", 
      "+\t\t (data & 0x0028)     | // bit 3, 5", 
      "+\t\t((data & 0x2000)>>7) | // bit 6", 
      "+\t\t((data & 0x0040)<<1);", 
      "+}", 
      "+", 
      "+static uint8_t read_byte(struct mtd_info *mtd)", 
      "+{", 
      "+\tstruct nand_chip *this = mtd->priv;", 
      "+\treturn ReadConversion(cpu_to_le16(readw(this->IO_ADDR_R)));", 
      "+}", 
      "+", 
      "+/**", 
      "+ * Write data from the buffer to the chip", 
      "+ */", 
      "+static void write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)", 
      "+{", 
      "+\tint i;", 
      "+\tstruct nand_chip *this = mtd->priv;", 
      "+", 
      "+\tfor (i = 0; i < len; i++) {", 
      "+\t\twritew(WriteConversion(buf[i]), this->IO_ADDR_W);", 
      "+\t}", 
      "+}", 
      "+", 
      "+/**", 
      "+ * Read data from the chip into the buffer", 
      "+ */", 
      "+static void read_buf(struct mtd_info *mtd, uint8_t *buf, int len)", 
      "+{", 
      "+\tint i;", 
      "+\tstruct nand_chip *this = mtd->priv;", 
      "+", 
      "+\tfor (i = 0; i < len; i++) {", 
      "+\t\tbuf[i] = ReadConversion(readw(this->IO_ADDR_R));", 
      "+\t}", 
      "+}", 
      "+", 
      "+/**", 
      "+ * Verify buffer contents against the chip data", 
      "+ */", 
      "+static int verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)", 
      "+{", 
      "+\tint i;", 
      "+\tstruct nand_chip *this = mtd->priv;", 
      "+", 
      "+\tfor (i = 0; i < len; i++) {", 
      "+\t\tif (buf[i] != ReadConversion(readw(this->IO_ADDR_R))) {", 
      "+\t\t\treturn -EFAULT;", 
      "+\t\t}", 
      "+\t}", 
      "+", 
      "+\treturn 0;", 
      "+}", 
      "+", 
      "+/*", 
      "+ * Hardwarespecific funtion for controlling ALE/CLE/nCE. Also used to write", 
      "+ * command and address.", 
      "+ */", 
      "+static void cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)", 
      "+{", 
      "+\tstruct nand_chip *this = mtd->priv;", 
      "+", 
      "+\tif (ctrl & NAND_CTRL_CHANGE) {", 
      "+\t\tint value;", 
      "+", 
      "+\t\tvalue = (ctrl & NAND_NCE) ? 1 : 0;", 
      "+\t\tif (value != nand_cs) {", 
      "+\t\t\tif (value) {", 
      "+\t\t\t\tVIP19XX_EMI_ENABLE_CS(this->priv,", 
      "+\t\t\t\t\t\t      VIP19XX_NAND_FLASH_EMI_BANK);", 
      "+\t\t\t}", 
      "+\t\t\telse {", 
      "+\t\t\t\tVIP19XX_EMI_DISABLE_CS(this->priv,", 
      "+\t\t\t\t\t\t       VIP19XX_NAND_FLASH_EMI_BANK);", 
      "+\t\t\t}", 
      "+\t\t\tnand_cs = value;", 
      "+\t\t}", 
      "+", 
      "+\t\tvalue = (ctrl & NAND_CLE) ? 1 : 0;", 
      "+\t\tstpio_set_pin(nand_cle, value);", 
      "+", 
      "+\t\tvalue = (ctrl & NAND_ALE) ? 1 : 0;", 
      "+\t\tstpio_set_pin(nand_ale, value);", 
      "+\t}", 
      "+", 
      "+\tif (dat != NAND_CMD_NONE) {", 
      "+\t\tuint8_t tmp = dat;", 
      "+\t\tthis->write_buf(mtd, &tmp, 1);", 
      "+\t}", 
      "+}", 
      "+", 
      "+/*", 
      "+ * Hardware specific wait function for wait on ready.", 
      "+ */", 
      "+static int waitfunc(struct mtd_info *mtd, struct nand_chip *this)", 
      "+{", 
      "+\tthis->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);", 
      "+", 
      "+\t/*", 
      "+\t * Chip busy, wait for ready", 
      "+\t * Using stpio with IRQ doesn't seem to work correctly. We get stuck", 
      "+\t * after Schedule() is called (see wait_event_interrupible in", 
      "+\t * linux/wait.h). Using busy-wait for now.", 
      "+\t */", 
      "+\twhile (stpio_get_pin(nand_rbusy) != 1);", 
      "+", 
      "+\treturn (int)this->read_byte(mtd);", 
      "+}", 
      "+", 
      "+/* Returns 0 if the nand is busy, 1 if it is ready */", 
      "+static int dev_ready(struct mtd_info *mtd)", 
      "+{", 
      "+        return stpio_get_pin(nand_rbusy);", 
      "+}", 
      "+", 
      "+static int __init init(void)", 
      "+{", 
      "+\tstruct nand_chip *this;", 
      "+\tint err = 0;", 
      "+", 
      "+\t/* Request PIO pins */", 
      "+\tnand_cle = stpio_request_pin(nand_port,", 
      "+\t\t\t\t     cle_pin, \"NAND IO\", STPIO_OUT);", 
      "+\tnand_ale = stpio_request_pin(nand_port,", 
      "+\t\t\t\t     ale_pin, \"NAND IO\", STPIO_OUT);", 
      "+\tnand_rbusy = stpio_request_pin(nand_port,", 
      "+\t\t\t\t       rbusy_pin, \"NAND IO\", STPIO_IN);", 
      "+", 
      "+\tif (nand_cle == NULL || nand_ale == NULL || nand_rbusy == NULL) {", 
      "+\t\tprintk(KERN_ERR NAME \": failed to allocate PIO pins\\n\");", 
      "+\t\terr = -EIO;", 
      "+\t\tgoto out;", 
      "+\t}", 
      "+", 
      "+\t/* Allocate memory for MTD device structure and private data */", 
      "+\tnand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip),", 
      "+\t\t\t   GFP_KERNEL);", 
      "+\tif (!nand_mtd) {", 
      "+\t\tprintk(KERN_ERR NAME \": unable to allocate VIP19xx NAND MTD \"", 
      "+\t\t       \"device structure\\n\");", 
      "+\t\terr = -ENOMEM;", 
      "+\t\tgoto out_pio;", 
      "+\t}", 
      "+", 
      "+\t/* Get pointer to private data */", 
      "+\tthis = (struct nand_chip *)(&nand_mtd[1]);", 
      "+", 
      "+\t/* Initialize structures */", 
      "+\tmemset(nand_mtd, 0, sizeof(struct mtd_info));", 
      "+\tmemset(this, 0, sizeof(struct nand_chip));", 
      "+", 
      "+\tnand_mtd->owner = THIS_MODULE;", 
      "+", 
      "+\t/* Link the private data with the MTD structure */", 
      "+\tnand_mtd->priv = this;", 
      "+", 
      "+\t/* Set address of NAND IO lines */", 
      "+\tthis->IO_ADDR_R = ioremap_nocache(VIP19XX_NAND_FLASH_BASE,", 
      "+\t\t\t\t\t  VIP19XX_NAND_FLASH_SIZE);", 
      "+\tthis->IO_ADDR_W = this->IO_ADDR_R;", 
      "+", 
      "+\t/* Set address of hardware control function */", 
      "+\tthis->cmd_ctrl = cmd_ctrl;", 
      "+\t/* 15 us command delay time */", 
      "+\tthis->chip_delay = 15;", 
      "+\t/* Software ECC */", 
      "+\tthis->ecc.mode = NAND_ECC_SOFT;", 
      "+", 
      "+\tthis->waitfunc = waitfunc;", 
      "+\tthis->dev_ready = dev_ready;", 
      "+", 
      "+\t// Map the EMI config memory", 
      "+\tthis->priv = ioremap_nocache(VIP19XX_EMI_CONFIG_BASE, VIP19XX_EMI_CONFIG_SIZE);", 
      "+", 
      "+\t/* Scan to find existence of the device */", 
      "+\tif (nand_scan(nand_mtd, 1)) {", 
      "+\t\t/* Early 19xx boards had another NAND flash with different pin", 
      "+\t\t * layout. The code below is only used for that old flash. */", 
      "+", 
      "+\t\t/* Setup the EMIbus in 16 bit mode */", 
      "+\t\tunsigned long size;", 
      "+\t\tsize = readl(VIP19XX_EMI_CFG_DATA0(this->priv, VIP19XX_NAND_FLASH_EMI_BANK));", 
      "+\t\tsize &= ~VIP19XX_EMI_CFG_PORTSIZE_MASK;", 
      "+\t\tsize |= VIP19XX_EMI_CFG_PORTSIZE_16;", 
      "+\t\twritel(size, VIP19XX_EMI_CFG_DATA0(this->priv, VIP19XX_NAND_FLASH_EMI_BANK));", 
      "+", 
      "+\t\tthis->read_byte = read_byte;", 
      "+\t\tthis->write_buf = write_buf;", 
      "+\t\tthis->read_buf = read_buf;", 
      "+\t\tthis->verify_buf = verify_buf;", 
      "+", 
      "+\t\tif (nand_scan(nand_mtd, 1)) {", 
      "+\t\t\terr = -ENXIO;", 
      "+\t\t\tgoto out_mtd;", 
      "+\t\t}", 
      "+\t}", 
      "+", 
      "+\t/* Register the partitions */", 
      "+\tpartition_info[0].size = nand_mtd->size;", 
      "+\tadd_mtd_partitions(nand_mtd, partition_info,", 
      "+\t\t\t   ARRAY_SIZE(partition_info));", 
      "+", 
      "+\tgoto out;", 
      "+", 
      "+out_mtd:", 
      "+\tiounmap(this->priv);", 
      "+\tkfree(nand_mtd);", 
      "+out_pio:", 
      "+\tstpio_free_pin(nand_cle);", 
      "+\tstpio_free_pin(nand_ale);", 
      "+\tstpio_free_pin(nand_rbusy);", 
      "+out:", 
      "+\treturn err;", 
      "+}", 
      "+module_init(init);", 
      "+", 
      "+/* Clean up routine */", 
      "+static void __exit cleanup(void)", 
      "+{", 
      "+\tstruct nand_chip *this = nand_mtd->priv;", 
      "+", 
      "+\tstpio_free_pin(nand_cle);", 
      "+\tstpio_free_pin(nand_ale);", 
      "+\tstpio_free_pin(nand_rbusy);", 
      "+", 
      "+\tiounmap(this->IO_ADDR_R);", 
      "+\tiounmap(this->priv);", 
      "+", 
      "+\t/* Release resources, unregister device */", 
      "+\tnand_release(nand_mtd);", 
      "+", 
      "+\t/* Free the MTD device structure */", 
      "+\tkfree(nand_mtd);", 
      "+}", 
      "+module_exit(cleanup);", 
      "+", 
      "+MODULE_LICENSE(\"GPL\");", 
      "+MODULE_AUTHOR(\"Erik Johansson <erik.johansson@motorola.com>\");", 
      "+MODULE_DESCRIPTION(\"Motorola VIP19xx STB NAND flash driver\");"
    ]
  ]
]