diff options
Diffstat (limited to 'meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch')
-rw-r--r-- | meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch | 599 |
1 files changed, 0 insertions, 599 deletions
diff --git a/meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch b/meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch deleted file mode 100644 index d77e9d8fbd..0000000000 --- a/meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch +++ /dev/null @@ -1,599 +0,0 @@ -Index: linux-2.6.17/drivers/mtd/nand/cm-x270.c -=================================================================== ---- linux-2.6.17.orig/drivers/mtd/nand/cm-x270.c 2006-07-18 15:40:10.000000000 +0100 -+++ linux-2.6.17/drivers/mtd/nand/cm-x270.c 2006-07-19 15:35:18.000000000 +0100 -@@ -1,7 +1,13 @@ - /* -- * drivers/mtd/nand/cm-x270.c -+ * linux/drivers/mtd/nand/cmx270-nand.c -+ * -+ * Copyright (C) 2006 Compulab, Ltd. -+ * Mike Rapoport <mike@compulab.co.il> -+ * -+ * Derived from drivers/mtd/nand/h1910.c -+ * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) -+ * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) - * -- * Copyright (c) 2006, 8D Technologies inc. - * - * 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 -@@ -9,397 +15,269 @@ - * - * Overview: - * This is a device driver for the NAND flash device found on the -- * cm-x270 compulab SBC. -- * -- * Changelog: -- * - April 2006, Raphael Assenat <raph@8d.com>: -- * Creation of the driver. -+ * CM-X270 board. - */ - --#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/init.h> -+#include <linux/module.h> - #include <linux/mtd/mtd.h> - #include <linux/mtd/nand.h> - #include <linux/mtd/partitions.h> --#include <asm/hardware.h> -+ - #include <asm/io.h> -+#include <asm/irq.h> -+ -+#include <asm/arch/hardware.h> - #include <asm/arch/pxa-regs.h> --#include <asm/arch/cm-x270.h> - -+#define GPIO_NAND_CS (11) -+#define GPIO_NAND_RB (89) - --static struct mtd_info *cmx270_mtd = NULL; --static void *cmx270_nand_io_base; --#define OFFSET_BASE 0 --#define OFFSET_CLE 4 --#define OFFSET_ALE 8 -- --#define DEFAULT_NUM_PARTITIONS 1 --static int nr_partitions; --static struct mtd_partition cmx270_default_partition_info[] = { -- { -- .name = "rootfs", -- .offset = 0, -- .size = MTDPART_SIZ_FULL, -- }, --}; -+/* This macro needed to ensure in-order operation of GPIO and local -+ * bus. Without both asm command and dummy uncached read there're -+ * states when NAND access is broken. I've looked for such macro(s) in -+ * include/asm-arm but found nothing approptiate. -+ * dmac_clean_range is close, but is makes cache invalidation -+ * unnecessary here and it cannot be used in module -+ */ -+#define DRAIN_WB() \ -+ do { \ -+ unsigned char dummy; \ -+ asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); \ -+ dummy=*((unsigned char*)UNCACHED_ADDR); \ -+ } while(0) - --static void cmx270_nand_hwcontrol(struct mtd_info *mtd, int cmd) --{ -- udelay(1); -- switch(cmd) -+/* MTD structure for CM-X270 board */ -+static struct mtd_info *cmx270_nand_mtd; -+ -+/* remaped IO address of the device */ -+static void __iomem *cmx270_nand_io; -+ -+/* -+ * Define static partitions for flash device -+ */ -+static struct mtd_partition partition_info[] = { - { -- case NAND_CTL_SETNCE: -- GPCR(CM_X270_GPIO_NAND_CS) = GPIO_bit(CM_X270_GPIO_NAND_CS); -- break; -- case NAND_CTL_CLRNCE: -- GPSR(CM_X270_GPIO_NAND_CS) = GPIO_bit(CM_X270_GPIO_NAND_CS); -- break; -+ .name = "cmx270-0", -+ .offset = 0, -+ .size = MTDPART_SIZ_FULL - } -- udelay(1); --} -- --static int cmx270_nand_device_ready(struct mtd_info *mtd) --{ -- /* I was getting ecc errors on reads, but adding this delay -- made the problem disappear. There is probably a timing -- issue somewhere. */ -- //ndelay (500); -- udelay (25); -+}; -+#define NUM_PARTITIONS (ARRAY_SIZE(partition_info)) - -- return GPLR(CM_X270_GPIO_NAND_RB) & GPIO_bit(CM_X270_GPIO_NAND_RB); --} -+const char *part_probes[] = { "cmdlinepart", NULL }; - --static u_char cmx270_nand_read_byte(struct mtd_info *mtd) -+static u_char cmx270_read_byte(struct mtd_info *mtd) - { - struct nand_chip *this = mtd->priv; --// unsigned long raw = readl(this->IO_ADDR_R); -- unsigned char res = ( readl(this->IO_ADDR_R) >> 16 ) & 0xff; -- return res; --} - --static void cmx270_nand_write_byte(struct mtd_info *mtd, u_char byte) --{ -- struct nand_chip *this = mtd->priv; -- writel( (byte<<16), this->IO_ADDR_W ); -- udelay(1); -+ return (readl(this->IO_ADDR_R) >> 16); - } - --static void cmx270_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) -+static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len) - { - int i; - struct nand_chip *this = mtd->priv; - - for (i=0; i<len; i++) -- writel((buf[i]<<16), this->IO_ADDR_W); -- udelay(1); -+ writel((*buf++ << 16), this->IO_ADDR_W); - } - --static void cmx270_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) -+static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len) - { - int i; - struct nand_chip *this = mtd->priv; - - for (i=0; i<len; i++) -- buf[i] = (readl(this->IO_ADDR_R) >> 16 ) & 0xff; -- udelay(1); -+ *buf++ = readl(this->IO_ADDR_R) >> 16; - } - --static int cmx270_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) -+static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) - { - int i; - struct nand_chip *this = mtd->priv; - - for (i=0; i<len; i++) -- if (buf[i] != ((readl(this->IO_ADDR_R) >> 16) & 0xff)) -+ if (buf[i] != (u_char)(readl(this->IO_ADDR_R) >> 16)) - return -EFAULT; -- udelay(1); - - return 0; - } - --static void cmx270_nand_write_ALE(struct mtd_info *mtd, const u_char byte) -+static inline void nand_cs_on(void) - { -- struct nand_chip *this = mtd->priv; -- writel( byte << 16 , this->IO_ADDR_W + OFFSET_ALE); -- udelay(1); -+ GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); - } - --static void cmx270_nand_write_CLE(struct mtd_info *mtd, const u_char byte) -+static void nand_cs_off(void) - { -- struct nand_chip *this = mtd->priv; -- writel( byte << 16 , this->IO_ADDR_W + OFFSET_CLE); -- udelay(1); -+ DRAIN_WB(); -+ -+ GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); - } - --/* Same as nand_core:nand_command() but with different memory -- * addresses for writing to ALE and CLE and without 16 bit support. -+/* -+ * hardware specific access to control-lines - */ --static void cmx270_nand_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) -+static void cmx270_hwcontrol(struct mtd_info *mtd, int cmd) - { -- register struct nand_chip *this = mtd->priv; -+ struct nand_chip* this = (struct nand_chip *) (mtd->priv); -+ unsigned int nandaddr = (unsigned int)this->IO_ADDR_R; - --// printk("cmd: 0x%02x col: 0x%x page_addr: 0x%x\n", --// command, column, page_addr); -- -- if (command == NAND_CMD_SEQIN) { -- int readcmd; -- -- if (column >= mtd->oobblock) { -- /* OOB area */ -- column -= mtd->oobblock; -- readcmd = NAND_CMD_READOOB; -- } else if (column < 256) { -- /* First 256 bytes --> READ0 */ -- readcmd = NAND_CMD_READ0; -- } else { -- column -= 256; -- readcmd = NAND_CMD_READ1; -- } -- cmx270_nand_write_CLE(mtd, readcmd); -- } -- cmx270_nand_write_CLE(mtd, command); -+ DRAIN_WB(); - -- if (column != -1 || page_addr != -1) { -- -- /* Serially input address */ -- if (column != -1) { -- cmx270_nand_write_ALE(mtd, column); -- } -- if (page_addr != -1) { -- cmx270_nand_write_ALE(mtd, (unsigned char) (page_addr & 0xff)); -- cmx270_nand_write_ALE(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); -- /* One more address cycle for devices > 32MiB */ -- if (this->chipsize > (32 << 20)) -- cmx270_nand_write_ALE(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); -- } -- } -+ switch(cmd) { - -- /* -- * program and erase have their own busy handlers -- * status and sequential in needs no delay -- */ -- switch (command) { -- -- case NAND_CMD_PAGEPROG: -- case NAND_CMD_ERASE1: -- case NAND_CMD_ERASE2: -- case NAND_CMD_SEQIN: -- case NAND_CMD_STATUS: -- return; -- -- case NAND_CMD_RESET: -- if (this->dev_ready) -- break; -- udelay(this->chip_delay); -- cmx270_nand_write_CLE(mtd, NAND_CMD_STATUS); -- while ( !(this->read_byte(mtd) & 0x40)); -- return; -- -- /* This applies to read commands */ -- default: -- /* -- * If we don't have access to the busy pin, we apply the given -- * command delay -- */ -- if (!this->dev_ready) { -- udelay(this->chip_delay); -- return; -- } -- } -- -- /* Apply this short delay always to ensure that we do wait tWB in -- * any case on any machine. */ -- ndelay (100); -- /* wait until command is processed */ -- while (!this->dev_ready(mtd)); -- ndelay (100); -+ case NAND_CTL_SETCLE: -+ nandaddr |= (1 << 2); -+ this->IO_ADDR_R = (void __iomem*)nandaddr; -+ this->IO_ADDR_W = (void __iomem*)nandaddr; -+ break; -+ case NAND_CTL_CLRCLE: -+ nandaddr &= ~(1 << 2); -+ this->IO_ADDR_R = (void __iomem*)nandaddr; -+ this->IO_ADDR_W = (void __iomem*)nandaddr; -+ break; -+ -+ case NAND_CTL_SETALE: -+ nandaddr |= (1 << 3); -+ this->IO_ADDR_R = (void __iomem*)nandaddr; -+ this->IO_ADDR_W = (void __iomem*)nandaddr; -+ break; -+ case NAND_CTL_CLRALE: -+ nandaddr &= ~(1 << 3); -+ this->IO_ADDR_R = (void __iomem*)nandaddr; -+ this->IO_ADDR_W = (void __iomem*)nandaddr; -+ break; -+ -+ case NAND_CTL_SETNCE: -+ nand_cs_on(); -+ break; -+ case NAND_CTL_CLRNCE: -+ nand_cs_off(); -+ break; -+ } -+ -+ DRAIN_WB(); - } - --/* Same as nand_core:nand_command_lp() but with different memory -- * addresses for writing to ALE and CLE and without 16 bit support. -+ -+/* -+ * read device ready pin - */ --static void cmx270_nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr) -+static int cmx270_device_ready(struct mtd_info *mtd) - { -- register struct nand_chip *this = mtd->priv; -- -- /* Emulate NAND_CMD_READOOB */ -- if (command == NAND_CMD_READOOB) { -- column += mtd->oobblock; -- command = NAND_CMD_READ0; --// printk("Read OOB: column: $%x, page: $%x\n", column, page_addr); -- } -- -- /* Write out the command to the device. */ -- cmx270_nand_write_CLE(mtd, command); -- -- if (column != -1 || page_addr != -1) { -- -- /* Serially input address */ -- if (column != -1) { -- cmx270_nand_write_ALE(mtd, column & 0xff); -- cmx270_nand_write_ALE(mtd, column >> 8); -- if ((column >> 8) > 0xf) { -- printk("out of range column\n"); -- } -- } -- if (page_addr != -1) { -- cmx270_nand_write_ALE(mtd, (unsigned char) (page_addr & 0xff)); -- cmx270_nand_write_ALE(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); -- /* One more address cycle for devices > 128MiB */ -- if (this->chipsize > (128 << 20)) { -- cmx270_nand_write_ALE(mtd, (unsigned char) ((page_addr >> 16) & 0xff)); -- } -- } -- } -+ DRAIN_WB(); - -- udelay(1); -- -- /* -- * program and erase have their own busy handlers -- * status and sequential in needs no delay -- */ -- switch (command) { -- -- case NAND_CMD_CACHEDPROG: -- case NAND_CMD_PAGEPROG: -- case NAND_CMD_ERASE1: -- case NAND_CMD_ERASE2: -- case NAND_CMD_SEQIN: -- case NAND_CMD_STATUS: -- case NAND_CMD_DEPLETE1: -- return; -- -- /* -- * read error status commands require only a short delay -- */ -- case NAND_CMD_STATUS_ERROR: -- case NAND_CMD_STATUS_ERROR0: -- case NAND_CMD_STATUS_ERROR1: -- case NAND_CMD_STATUS_ERROR2: -- case NAND_CMD_STATUS_ERROR3: -- udelay(this->chip_delay); -- return; -- -- case NAND_CMD_RESET: -- if (this->dev_ready) -- break; -- udelay(this->chip_delay); -- cmx270_nand_write_CLE(mtd, NAND_CMD_STATUS); -- while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); -- return; -- -- case NAND_CMD_READ0: -- /* Write out the start read command */ -- cmx270_nand_write_CLE(mtd, NAND_CMD_READSTART); -- /* Fall through into ready check */ -- -- /* This applies to read commands */ -- default: -- /* -- * If we don't have access to the busy pin, we apply the given -- * command delay -- */ -- if (!this->dev_ready) { -- udelay (this->chip_delay); -- return; -- } -- } -- -- /* Apply this short delay always to ensure that we do wait tWB in -- * any case on any machine. */ -- ndelay (100); -- /* wait until command is processed */ -- while (!this->dev_ready(mtd)); -+ return (GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB)); - } - -- --#ifdef CONFIG_MTD_PARTITIONS --const char *part_probes[] = { "cmdlinepart", NULL }; --#endif -- --int __init cmx270_nand_init(void) -+/* -+ * Main initialization routine -+ */ -+static int __devinit cmx270_init(void) - { - struct nand_chip *this; -- struct mtd_partition* cmx270_partition_info; -- int err = 0; -- -- pxa_gpio_mode(CM_X270_GPIO_NAND_RB); -+ const char *part_type; -+ struct mtd_partition *mtd_parts; -+ int mtd_parts_nb = 0; -+ int ret; - -- GPSR(CM_X270_GPIO_NAND_CS) = GPIO_bit(CM_X270_GPIO_NAND_CS); -- pxa_gpio_mode(CM_X270_GPIO_NAND_CS | GPIO_OUT); -- - /* Allocate memory for MTD device structure and private data */ -- cmx270_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), -- GFP_KERNEL); -- if (!cmx270_mtd) { -- printk(KERN_WARNING "Unable to allocate cm-x270 NAND mtd device structure.\n"); -- err = -ENOMEM; -- goto out; -+ cmx270_nand_mtd = kzalloc(sizeof(struct mtd_info) + -+ sizeof(struct nand_chip), -+ GFP_KERNEL); -+ if (!cmx270_nand_mtd) { -+ printk("Unable to allocate CM-X270 NAND MTD device structure.\n"); -+ return -ENOMEM; - } - -- /* map physical address */ -- cmx270_nand_io_base = ioremap(CM_X270_NAND_PHYS, 0x100); -- if (!cmx270_nand_io_base) { -- err = -EIO; -- goto out_mtd; -+ cmx270_nand_io = ioremap(PXA_CS1_PHYS, 12); -+ if (!cmx270_nand_io) { -+ printk("Unable to ioremap NAND device\n"); -+ ret = -EINVAL; -+ goto err1; - } - - /* Get pointer to private data */ -- this = (struct nand_chip *)(&cmx270_mtd[1]); -- -- /* Initialize structures */ -- memset((char *) cmx270_mtd, 0, sizeof(struct mtd_info)); -- memset((char *) this, 0, sizeof(struct nand_chip)); -+ this = (struct nand_chip *)(&cmx270_nand_mtd[1]); - - /* Link the private data with the MTD structure */ -- cmx270_mtd->priv = this; -+ cmx270_nand_mtd->owner = THIS_MODULE; -+ cmx270_nand_mtd->priv = this; - -- this->IO_ADDR_R = cmx270_nand_io_base; -- this->IO_ADDR_W = cmx270_nand_io_base; -- this->read_byte = cmx270_nand_read_byte; -- this->write_byte = cmx270_nand_write_byte; -- this->write_buf = cmx270_nand_write_buf; -- this->read_buf = cmx270_nand_read_buf; -- this->verify_buf = cmx270_nand_verify_buf; -- this->hwcontrol = cmx270_nand_hwcontrol; -- this->dev_ready = cmx270_nand_device_ready; -- this->cmdfunc = cmx270_nand_command_lp; -- this->chip_delay = 25; -+ /* insert callbacks */ -+ this->IO_ADDR_R = cmx270_nand_io; -+ this->IO_ADDR_W = cmx270_nand_io; -+ this->hwcontrol = cmx270_hwcontrol; -+ this->dev_ready = cmx270_device_ready; -+ -+ /* 15 us command delay time */ -+ this->chip_delay = 20; - this->eccmode = NAND_ECC_SOFT; - -- /* Scan to find existance of the device */ -- if (nand_scan(cmx270_mtd, 1)) { -- err = -ENXIO; -- goto out_ior; -+ /* read/write functions */ -+ this->read_byte = cmx270_read_byte; -+ this->read_buf = cmx270_read_buf; -+ this->write_buf = cmx270_write_buf; -+ this->verify_buf = cmx270_verify_buf; -+ -+ /* Scan to find existence of the device */ -+ if (nand_scan (cmx270_nand_mtd, 1)) { -+ printk(KERN_NOTICE "No NAND device\n"); -+ ret = -ENXIO; -+ goto err2; -+ } -+ -+#ifdef CONFIG_MTD_CMDLINE_PARTS -+ mtd_parts_nb = parse_mtd_partitions(cmx270_nand_mtd, part_probes, -+ &mtd_parts, 0); -+ if (mtd_parts_nb > 0) -+ part_type = "command line"; -+ else -+ mtd_parts_nb = 0; -+#endif -+ if (!mtd_parts_nb) { -+ mtd_parts = partition_info; -+ mtd_parts_nb = NUM_PARTITIONS; -+ part_type = "static"; - } - - /* Register the partitions */ -- cmx270_mtd->name = "cmx270-mtd"; -- nr_partitions = parse_mtd_partitions(cmx270_mtd, part_probes, &cmx270_partition_info, 0); -- if (nr_partitions <= 0) { -- nr_partitions = DEFAULT_NUM_PARTITIONS; -- cmx270_partition_info = cmx270_default_partition_info; -- } -+ printk(KERN_NOTICE "Using %s partition definition\n", part_type); -+ ret = add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb); -+ if (ret) -+ goto err2; -+ -+ /* Return happy */ -+ return 0; -+ -+err2: -+ iounmap(cmx270_nand_io); -+err1: -+ kfree(cmx270_nand_mtd); -+ -+ return ret; - -- add_mtd_partitions(cmx270_mtd, cmx270_partition_info, nr_partitions); -- -- goto out; -- --out_ior: -- iounmap((void*) cmx270_nand_io_base); --out_mtd: -- kfree(cmx270_mtd); --out: -- return err; - } --module_init(cmx270_nand_init); -+module_init(cmx270_init); - --static void __exit cmx270_nand_cleanup(void) -+/* -+ * Clean up routine -+ */ -+static void __devexit cmx270_cleanup(void) - { -- nand_release(cmx270_mtd); -- kfree(cmx270_mtd); -+ /* Release resources, unregister device */ -+ nand_release(cmx270_nand_mtd); -+ -+ iounmap(cmx270_nand_io); -+ -+ /* Free the MTD device structure */ -+ kfree (cmx270_nand_mtd); - } -+module_exit(cmx270_cleanup); - - MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Raphael Assenat <raph@8d.com>"); --MODULE_DESCRIPTION("NAND flash driver for cm-x270 boards"); -- -+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); -+MODULE_DESCRIPTION("NAND flash driver for Compulab CM-X270 Module"); |