* [PATCH] NAND Flash support for Intel IXP4xx platform
@ 2007-04-19 10:29 Ruslan V. Sushko
2007-04-20 8:25 ` Vitaly Wool
0 siblings, 1 reply; 14+ messages in thread
From: Ruslan V. Sushko @ 2007-04-19 10:29 UTC (permalink / raw)
To: linux-mtd
The patch adds glue logic to support MTD for NAND flash devices on Intel
IXP4xx based platform
Signed-off-by: rsushko@ru.mvista.com
-----
Index: linux-2.6/drivers/mtd/nand/Kconfig
===================================================================
--- linux-2.6.orig/drivers/mtd/nand/Kconfig
+++ linux-2.6/drivers/mtd/nand/Kconfig
@@ -143,6 +143,13 @@ config MTD_NAND_S3C2410_CLKSTOP
when the is NAND chip selected or released, but will save
approximately 5mA of power when there is nothing happening.
+config MTD_NAND_IXP4XX
+ tristate "Support for NAND Flash on Intel IXP4XX based systems"
+ depends on MTD_NAND && ARCH_IXP4XX
+ help
+ This enable the use of NAND flash on Intel IXP400 based platforms.
+ Currently this is only supported on KIXRP435 platform.
+
config MTD_NAND_DISKONCHIP
tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
depends on MTD_NAND && EXPERIMENTAL
Index: linux-2.6/drivers/mtd/nand/Makefile
===================================================================
--- linux-2.6.orig/drivers/mtd/nand/Makefile
+++ linux-2.6/drivers/mtd/nand/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_MTD_NAND_CS553X) += cs553x
obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o
obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
+obj-$(CONFIG_MTD_NAND_IXP4XX) += ixp4xx_nand.o
nand-objs := nand_base.o nand_bbt.o
cafe_nand-objs := cafe.o cafe_ecc.o
Index: linux-2.6/drivers/mtd/nand/ixp4xx_nand.c
===================================================================
--- /dev/null
+++ linux-2.6/drivers/mtd/nand/ixp4xx_nand.c
@@ -0,0 +1,221 @@
+/*
+ * drivers/mtd/nand/ixp4xx_nand.c
+ *
+ * Copyright (C) 2006 Intel Corporation.
+ * Copyright (C) 2007 MontaVista Software, 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.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/arch/nand.h>
+#include <asm/hardware.h>
+#include <asm/delay.h>
+
+/*
+ * MTD structure for NAND controller
+ */
+static struct mtd_info *ixp4xx_mtd = NULL;
+static struct mtd_partition *ixp4xx_nand_parts = NULL;
+const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct ixp4xx_faddr_t {
+ int offset;
+ void (*chip_select)(unsigned int ctrl);
+} ixp4xx_faddr_info = {0, NULL};
+
+/**
+ * ixp_write_buf - write buffer to chip
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ *
+ * write function for 8bit buswith
+ */
+static void ixp_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+ struct ixp4xx_faddr_t *addr_info = this->priv;
+
+ for ( i = 0 ; i < len ; i++ )
+ writeb(buf[i], this->IO_ADDR_W + addr_info->offset);
+}
+
+static void
+ixp4xx_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ struct ixp4xx_faddr_t *addr_info = this->priv;
+ if (ctrl & NAND_CTRL_CHANGE) {
+ addr_info->offset = (ctrl & NAND_CLE) ? 1 : 0;
+ addr_info->offset |= (ctrl & NAND_ALE) ? 2 : 0;
+ if (addr_info->chip_select)
+ addr_info->chip_select(ctrl);
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, this->IO_ADDR_W + addr_info->offset);
+}
+
+static int
+ixp4xx_nand_flash_probe(struct platform_device *dev)
+{
+ int err;
+ int nb_of_parts;
+ struct nand_chip *this;
+ void __iomem *nand_io_base;
+ struct ixp4xx_nand_platform_data *plat = dev->dev.platform_data;
+
+ if (!plat)
+ return -ENODEV;
+
+ if (plat->width != 1) {
+ printk(KERN_ERR "%s: %d bits bus width is not support for "
+ "ixp4xx driver\n", __FUNCTION__, plat->width * 8);
+ return -EINVAL;
+ }
+
+ if (plat->init) {
+ err = plat->init();
+ if (err)
+ return err;
+ }
+
+ /* Allocate memory for MTD device structure and private data */
+ ixp4xx_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
+ GFP_KERNEL);
+
+ if (ixp4xx_mtd == NULL) {
+ printk (KERN_ERR "Fail on mem alloc for NAND MTD dev\n");
+ return -ENOMEM;
+ }
+
+ /* Initialize structures and build the linkage to private data */
+ memset(ixp4xx_mtd, 0, sizeof(struct mtd_info)+sizeof(struct nand_chip));
+ this = (struct nand_chip *)(&ixp4xx_mtd[1]);
+
+ ixp4xx_mtd->priv = this;
+
+ ixp4xx_mtd->owner = THIS_MODULE;
+ ixp4xx_mtd->name = "ixp4xx-nand";
+
+ /* ioremap the io of NAND Flash */
+ nand_io_base = ioremap(dev->resource->start,
+ dev->resource->end - dev->resource->start + 1);
+ if (!nand_io_base) {
+ printk (KERN_ERR "Unable to map nand flash IO space\n");
+ err = -EIO;
+ goto error;
+ }
+
+ ixp4xx_faddr_info.offset = 0;
+ ixp4xx_faddr_info.chip_select = plat->chip_select;
+
+ /* Set address of hardware control function */
+ this->cmd_ctrl = ixp4xx_hwcontrol;
+ this->dev_ready = NULL;/* KIXRP435 has no GPIO pins route to R/B */
+ this->chip_delay = 30; /* 30 us command delay time */
+ this->ecc.mode = NAND_ECC_SOFT;
+ this->options = NAND_NO_AUTOINCR;
+ this->IO_ADDR_R = nand_io_base;
+ this->IO_ADDR_W = nand_io_base;
+ this->priv = &ixp4xx_faddr_info;
+ this->write_buf = ixp_write_buf;
+
+ /* Scan to find existence of the device */
+ if (nand_scan(ixp4xx_mtd, 1)) {
+ err = -ENXIO;
+ goto error;
+ }
+
+ nb_of_parts = parse_mtd_partitions(ixp4xx_mtd, part_probes,
+ &ixp4xx_nand_parts, 0);
+
+ if ( nb_of_parts <= 0 ) { /* No partition from parsing, use default */
+ printk(KERN_INFO "Loading default partition table\n");
+ ixp4xx_nand_parts = plat->parts;
+ nb_of_parts = plat->nr_parts;
+ }
+
+ /* Register the partitions */
+ err = add_mtd_partitions(ixp4xx_mtd, ixp4xx_nand_parts, nb_of_parts);
+ if (err) {
+ printk(KERN_ERR "Failed to add MTD partitions\n");
+ if ( ixp4xx_nand_parts != plat->parts )
+ kfree(ixp4xx_nand_parts);
+ goto error;
+ }
+ return 0;
+
+error:
+ if (nand_io_base)
+ iounmap ((void *)nand_io_base);
+
+ if(ixp4xx_mtd)
+ kfree (ixp4xx_mtd);
+ return err;
+}
+
+static int
+ixp4xx_nand_flash_remove(struct platform_device *dev)
+{
+ struct ixp4xx_nand_platform_data *plat = dev->dev.platform_data;
+ struct nand_chip *this = (struct nand_chip *)&ixp4xx_mtd[1];
+
+ if (plat->exit)
+ plat->exit();
+
+ /* Unmap IO */
+ iounmap((void *)this->IO_ADDR_W);
+
+ /* Release resources, unregister device */
+ nand_release(ixp4xx_mtd);
+
+ /* Free the MTD device structure */
+ kfree(ixp4xx_mtd);
+
+ /* Free the parsed partition table */
+ if (ixp4xx_nand_parts != plat->parts)
+ kfree(ixp4xx_nand_parts);
+ return 0;
+}
+
+static struct platform_driver ixp4xx_nand_flash_driver = {
+ .probe = ixp4xx_nand_flash_probe,
+ .remove = ixp4xx_nand_flash_remove,
+ .driver = {
+ .name = "IXP4XX-NAND-Flash",
+ },
+};
+
+static int __init ixp4xx_nand_flash_init(void)
+{
+ return platform_driver_register(&ixp4xx_nand_flash_driver);
+}
+
+static void __exit ixp4xx_nand_flash_exit(void)
+{
+ platform_driver_unregister(&ixp4xx_nand_flash_driver);
+}
+
+module_init(ixp4xx_nand_flash_init);
+module_exit(ixp4xx_nand_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on "
+ "IXP4xx-based platform");
+
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-19 10:29 [PATCH] NAND Flash support for Intel IXP4xx platform Ruslan V. Sushko
@ 2007-04-20 8:25 ` Vitaly Wool
2007-04-20 14:16 ` Ruslan V. Sushko
2007-04-24 10:33 ` Ruslan V. Sushko
0 siblings, 2 replies; 14+ messages in thread
From: Vitaly Wool @ 2007-04-20 8:25 UTC (permalink / raw)
To: Ruslan V. Sushko; +Cc: linux-mtd
Ruslan V. Sushko wrote:
> +static struct ixp4xx_faddr_t {
> + int offset;
> + void (*chip_select)(unsigned int ctrl);
> +} ixp4xx_faddr_info = {0, NULL};
>
ixp4xx_faddr_t is a nice name for a structure ;)
What the initialization to {0, NULL} is for?
Also, if this is a per-chip thing as might be concluded by placing its
pointer into this->priv, why do you make it static structure?
Same goes for
> +static struct mtd_info *ixp4xx_mtd = NULL;
> +static struct mtd_partition *ixp4xx_nand_parts = NULL;
>
> +
> + for ( i = 0 ; i < len ; i++ )
> + writeb(buf[i], this->IO_ADDR_W + addr_info->offset);
>
Wrong whitespacing.
> +}
> +
> +static void
> +ixp4xx_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
> +{
> + struct nand_chip *this = mtd->priv;
> + struct ixp4xx_faddr_t *addr_info = this->priv;
> + if (ctrl & NAND_CTRL_CHANGE) {
> + addr_info->offset = (ctrl & NAND_CLE) ? 1 : 0;
> + addr_info->offset |= (ctrl & NAND_ALE) ? 2 : 0;
> + if (addr_info->chip_select)
> + addr_info->chip_select(ctrl);
> + }
> +
> + if (cmd != NAND_CMD_NONE)
> + writeb(cmd, this->IO_ADDR_W + addr_info->offset);
> +}
>
Wait please, can you explain the logic here?
It looks like you'll be writing by ixp_write_buf to different base
addresses depending on how ctrl was set.
Is this the expected behavior?
> + if ( nb_of_parts <= 0 ) { /* No partition from parsing, use default */
>
Wrong whitespacing.
> + printk(KERN_INFO "Loading default partition table\n");
> + ixp4xx_nand_parts = plat->parts;
> + nb_of_parts = plat->nr_parts;
> + }
> +
> + /* Register the partitions */
> + err = add_mtd_partitions(ixp4xx_mtd, ixp4xx_nand_parts, nb_of_parts);
> + if (err) {
> + printk(KERN_ERR "Failed to add MTD partitions\n");
> + if ( ixp4xx_nand_parts != plat->parts )
> + kfree(ixp4xx_nand_parts);
>
Wrong indentation.
Moreover, if the number of partitions obtained by parse_mtd_partitions
is the same as the one provided by platform data, you'll get leakage here.
Vitaly
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-20 8:25 ` Vitaly Wool
@ 2007-04-20 14:16 ` Ruslan V. Sushko
2007-04-24 7:21 ` Vitaly Wool
2007-04-24 10:33 ` Ruslan V. Sushko
1 sibling, 1 reply; 14+ messages in thread
From: Ruslan V. Sushko @ 2007-04-20 14:16 UTC (permalink / raw)
To: Vitaly Wool; +Cc: linux-mtd
Vitaly Wool wrote:
> Ruslan V. Sushko wrote:
>> +static struct ixp4xx_faddr_t {
>> + int offset;
>> + void (*chip_select)(unsigned int ctrl);
>> +} ixp4xx_faddr_info = {0, NULL};
>>
> ixp4xx_faddr_t is a nice name for a structure ;)
> What the initialization to {0, NULL} is for?
just through habit. What's wrong here?
> Also, if this is a per-chip thing as might be concluded by placing its
> pointer into this->priv, why do you make it static structure?
> Same goes for
>
>> +static struct mtd_info *ixp4xx_mtd = NULL;
>> +static struct mtd_partition *ixp4xx_nand_parts = NULL;
>> +
>> + for ( i = 0 ; i < len ; i++ )
>> + writeb(buf[i], this->IO_ADDR_W + addr_info->offset);
>>
> Wrong whitespacing.
Will fixed
>> +}
>> +
>> +static void
>> +ixp4xx_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
>> +{
>> + struct nand_chip *this = mtd->priv;
>> + struct ixp4xx_faddr_t *addr_info = this->priv;
>> + if (ctrl & NAND_CTRL_CHANGE) {
>> + addr_info->offset = (ctrl & NAND_CLE) ? 1 : 0;
>> + addr_info->offset |= (ctrl & NAND_ALE) ? 2 : 0;
>> + if (addr_info->chip_select)
>> + addr_info->chip_select(ctrl);
>> + }
>> +
>> + if (cmd != NAND_CMD_NONE)
>> + writeb(cmd, this->IO_ADDR_W + addr_info->offset);
>> +}
>>
> Wait please, can you explain the logic here?
> It looks like you'll be writing by ixp_write_buf to different base
> addresses depending on how ctrl was set.
> Is this the expected behavior?
Yes it is. Two low bits of address bus is connected to ALE/CLE signals.
Generally it not necessary for wrietbuff routine, but it will not be
error on this level, by the way I'll remove it. The hwcontrol must work
in this way.
>
>> + if ( nb_of_parts <= 0 ) { /* No partition from parsing, use
>> default */
>>
> Wrong whitespacing.
will fix
>> + printk(KERN_INFO "Loading default partition table\n");
>> + ixp4xx_nand_parts = plat->parts;
>> + nb_of_parts = plat->nr_parts;
>> + }
>> +
>> + /* Register the partitions */
>> + err = add_mtd_partitions(ixp4xx_mtd, ixp4xx_nand_parts,
>> nb_of_parts);
>> + if (err) {
>> + printk(KERN_ERR "Failed to add MTD partitions\n");
>> + if ( ixp4xx_nand_parts != plat->parts )
>> + kfree(ixp4xx_nand_parts);
>>
> Wrong indentation.
> Moreover, if the number of partitions obtained by parse_mtd_partitions
> is the same as the one provided by platform data, you'll get leakage
> here.
how this can happens? Please describe.
>
> Vitaly
>
Best reagards,
Ruslan Sushko
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-20 14:16 ` Ruslan V. Sushko
@ 2007-04-24 7:21 ` Vitaly Wool
2007-04-24 8:29 ` Ruslan V. Sushko
0 siblings, 1 reply; 14+ messages in thread
From: Vitaly Wool @ 2007-04-24 7:21 UTC (permalink / raw)
To: Ruslan V. Sushko; +Cc: linux-mtd, Vitaly Wool
> > What the initialization to {0, NULL} is for?
> just through habit. What's wrong here?
It's just useless.
> >> +
> >> + /* Register the partitions */
> >> + err = add_mtd_partitions(ixp4xx_mtd, ixp4xx_nand_parts,
> >> nb_of_parts);
> >> + if (err) {
> >> + printk(KERN_ERR "Failed to add MTD partitions\n");
> >> + if ( ixp4xx_nand_parts != plat->parts )
> >> + kfree(ixp4xx_nand_parts);
> >>
> > Wrong indentation.
> > Moreover, if the number of partitions obtained by parse_mtd_partitions
> > is the same as the one provided by platform data, you'll get leakage
> > here.
> how this can happens? Please describe.
Suppose that the number of partitions obtained by parse_mtd_partitions
is the same as configured statically. If add_mtd_partitions fails,
ixp4xx_nand_parts != plat->parts is false and kfree won't be called.
Vitaly
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 7:21 ` Vitaly Wool
@ 2007-04-24 8:29 ` Ruslan V. Sushko
2007-04-24 8:34 ` Vitaly Wool
0 siblings, 1 reply; 14+ messages in thread
From: Ruslan V. Sushko @ 2007-04-24 8:29 UTC (permalink / raw)
To: Vitaly Wool; +Cc: linux-mtd, Vitaly Wool
Vitaly Wool wrote:
>> >> +
>> >> + /* Register the partitions */
>> >> + err = add_mtd_partitions(ixp4xx_mtd, ixp4xx_nand_parts,
>> >> nb_of_parts);
>> >> + if (err) {
>> >> + printk(KERN_ERR "Failed to add MTD partitions\n");
>> >> + if ( ixp4xx_nand_parts != plat->parts )
>> >> + kfree(ixp4xx_nand_parts);
>> >>
>> > Wrong indentation.
>> > Moreover, if the number of partitions obtained by parse_mtd_partitions
>> > is the same as the one provided by platform data, you'll get leakage
>> > here.
>> how this can happens? Please describe.
>
> Suppose that the number of partitions obtained by parse_mtd_partitions
> is the same as configured statically. If add_mtd_partitions fails,
> ixp4xx_nand_parts != plat->parts is false and kfree won't be called.
>
> Vitaly
It's impossible because ixp4xx_nand_parts and plat->parts hold pointers
to mtd_partions structure, not number of partions. Number of partitions
held in nb_of_parts variable.
Thank you,
Ruslan
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 8:29 ` Ruslan V. Sushko
@ 2007-04-24 8:34 ` Vitaly Wool
0 siblings, 0 replies; 14+ messages in thread
From: Vitaly Wool @ 2007-04-24 8:34 UTC (permalink / raw)
To: Ruslan V. Sushko; +Cc: linux-mtd, Vitaly Wool
On 4/24/07, Ruslan V. Sushko <rsushko@ru.mvista.com> wrote:
> > Suppose that the number of partitions obtained by parse_mtd_partitions
> > is the same as configured statically. If add_mtd_partitions fails,
> > ixp4xx_nand_parts != plat->parts is false and kfree won't be called.
> It's impossible because ixp4xx_nand_parts and plat->parts hold pointers
> to mtd_partions structure, not number of partions. Number of partitions
> held in nb_of_parts variable.
Oh shoot, right, thanks!
Vitaly
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-20 8:25 ` Vitaly Wool
2007-04-20 14:16 ` Ruslan V. Sushko
@ 2007-04-24 10:33 ` Ruslan V. Sushko
2007-04-24 10:38 ` Lennert Buytenhek
1 sibling, 1 reply; 14+ messages in thread
From: Ruslan V. Sushko @ 2007-04-24 10:33 UTC (permalink / raw)
To: linux-mtd
The patch adds glue logic to support MTD for NAND flash devices on Intel
IXP4xx based platform
The patch made against the 2.6.21-rc4 kernel
Updated after Vitaly's comments
Signed-off-by: rsushko@ru.mvista.com <http://lists.infradead.org/mailman/listinfo/linux-mtd>
Index: linux-2.6/drivers/mtd/nand/Kconfig
===================================================================
--- linux-2.6.orig/drivers/mtd/nand/Kconfig
+++ linux-2.6/drivers/mtd/nand/Kconfig
@@ -143,6 +143,13 @@ config MTD_NAND_S3C2410_CLKSTOP
when the is NAND chip selected or released, but will save
approximately 5mA of power when there is nothing happening.
+config MTD_NAND_IXP4XX
+ tristate "Support for NAND Flash on Intel IXP4XX based systems"
+ depends on MTD_NAND && ARCH_IXP4XX
+ help
+ This enable the use of NAND flash on Intel IXP400 based platforms.
+ Currently this is only supported on KIXRP435 platform.
+
config MTD_NAND_DISKONCHIP
tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND
reimplementation) (EXPERIMENTAL)"
depends on MTD_NAND && EXPERIMENTAL
Index: linux-2.6/drivers/mtd/nand/Makefile
===================================================================
--- linux-2.6.orig/drivers/mtd/nand/Makefile
+++ linux-2.6/drivers/mtd/nand/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_MTD_NAND_CS553X) += cs553x
obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o
obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
+obj-$(CONFIG_MTD_NAND_IXP4XX) += ixp4xx_nand.o
nand-objs := nand_base.o nand_bbt.o
cafe_nand-objs := cafe.o cafe_ecc.o
Index: linux-2.6/drivers/mtd/nand/ixp4xx_nand.c
===================================================================
--- /dev/null
+++ linux-2.6/drivers/mtd/nand/ixp4xx_nand.c
@@ -0,0 +1,221 @@
+/*
+ * drivers/mtd/nand/ixp4xx_nand.c
+ *
+ * Copyright (C) 2006 Intel Corporation.
+ * Copyright (C) 2007 MontaVista Software, 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.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/arch/nand.h>
+#include <asm/hardware.h>
+#include <asm/delay.h>
+
+/*
+ * MTD structure for NAND controller
+ */
+static struct mtd_info *ixp4xx_mtd = NULL;
+static struct mtd_partition *ixp4xx_nand_parts = NULL;
+const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct ixp4xx_faddr_info_t {
+ int offset;
+ void (*chip_select)(unsigned int ctrl);
+} ixp4xx_faddr_info;
+
+/**
+ * ixp_write_buf - write buffer to chip
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ *
+ * write function for 8bit buswith
+ */
+static void
+ixp_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++ )
+ writeb(buf[i], this->IO_ADDR_W);
+}
+
+static void
+ixp4xx_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ struct ixp4xx_faddr_info_t *addr_info = this->priv;
+ if (ctrl & NAND_CTRL_CHANGE) {
+ addr_info->offset = (ctrl & NAND_CLE) ? IXP4XX_NAND_CLE : 0;
+ addr_info->offset |= (ctrl & NAND_ALE) ? IXP4XX_NAND_ALE : 0;
+ if (addr_info->chip_select)
+ addr_info->chip_select(ctrl);
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, this->IO_ADDR_W + addr_info->offset);
+}
+
+static int
+ixp4xx_nand_flash_probe(struct platform_device *dev)
+{
+ int err;
+ int nb_of_parts;
+ struct nand_chip *this;
+ void __iomem *nand_io_base;
+ struct ixp4xx_nand_platform_data *plat = dev->dev.platform_data;
+
+ if (!plat)
+ return -ENODEV;
+
+ if (plat->width != 1) {
+ printk(KERN_ERR "%s: %d bits bus width is not support for "
+ "ixp4xx driver\n", __FUNCTION__, plat->width * 8);
+ return -EINVAL;
+ }
+
+ if (plat->init) {
+ err = plat->init();
+ if (err)
+ return err;
+ }
+
+ /* Allocate memory for MTD device structure and private data */
+ ixp4xx_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct
nand_chip),
+ GFP_KERNEL);
+
+ if (ixp4xx_mtd == NULL) {
+ printk (KERN_ERR "Fail on mem alloc for NAND MTD dev\n");
+ return -ENOMEM;
+ }
+
+ /* Initialize structures and build the linkage to private data */
+ memset(ixp4xx_mtd, 0, sizeof(struct mtd_info)+sizeof(struct
nand_chip));
+ this = (struct nand_chip *)(&ixp4xx_mtd[1]);
+
+ ixp4xx_mtd->priv = this;
+
+ ixp4xx_mtd->owner = THIS_MODULE;
+ ixp4xx_mtd->name = "ixp4xx-nand";
+
+ /* ioremap the io of NAND Flash */
+ nand_io_base = ioremap(dev->resource->start,
+ dev->resource->end - dev->resource->start + 1);
+ if (!nand_io_base) {
+ printk (KERN_ERR "Unable to map nand flash IO space\n");
+ err = -EIO;
+ goto error;
+ }
+
+ ixp4xx_faddr_info.offset = 0;
+ ixp4xx_faddr_info.chip_select = plat->chip_select;
+
+ /* Set address of hardware control function */
+ this->cmd_ctrl = ixp4xx_hwcontrol;
+ this->dev_ready = NULL;/* KIXRP435 has no GPIO pins route to R/B */
+ this->chip_delay = 30; /* 30 us command delay time */
+ this->ecc.mode = NAND_ECC_SOFT;
+ this->options = NAND_NO_AUTOINCR;
+ this->IO_ADDR_R = nand_io_base;
+ this->IO_ADDR_W = nand_io_base;
+ this->priv = &ixp4xx_faddr_info;
+ this->write_buf = ixp_write_buf;
+
+ /* Scan to find existence of the device */
+ if (nand_scan(ixp4xx_mtd, 1)) {
+ err = -ENXIO;
+ goto error;
+ }
+
+ nb_of_parts = parse_mtd_partitions(ixp4xx_mtd, part_probes,
+ &ixp4xx_nand_parts, 0);
+
+ if (nb_of_parts <= 0) { /* No partition from parsing, use default */
+ printk(KERN_INFO "Loading default partition table\n");
+ ixp4xx_nand_parts = plat->parts;
+ nb_of_parts = plat->nr_parts;
+ }
+
+ /* Register the partitions */
+ err = add_mtd_partitions(ixp4xx_mtd, ixp4xx_nand_parts, nb_of_parts);
+ if (err) {
+ printk(KERN_ERR "Failed to add MTD partitions\n");
+ if(ixp4xx_nand_parts != plat->parts)
+ kfree(ixp4xx_nand_parts);
+ goto error;
+ }
+ return 0;
+
+error:
+ if (nand_io_base)
+ iounmap ((void *)nand_io_base);
+
+ if(ixp4xx_mtd)
+ kfree (ixp4xx_mtd);
+ return err;
+}
+
+static int
+ixp4xx_nand_flash_remove(struct platform_device *dev)
+{
+ struct ixp4xx_nand_platform_data *plat = dev->dev.platform_data;
+ struct nand_chip *this = (struct nand_chip *)&ixp4xx_mtd[1];
+
+ if (plat->exit)
+ plat->exit();
+
+ /* Unmap IO */
+ iounmap((void *)this->IO_ADDR_W);
+
+ /* Release resources, unregister device */
+ nand_release(ixp4xx_mtd);
+
+ /* Free the MTD device structure */
+ kfree(ixp4xx_mtd);
+
+ /* Free the parsed partition table */
+ if (ixp4xx_nand_parts != plat->parts)
+ kfree(ixp4xx_nand_parts);
+ return 0;
+}
+
+static struct platform_driver ixp4xx_nand_flash_driver = {
+ .probe = ixp4xx_nand_flash_probe,
+ .remove = ixp4xx_nand_flash_remove,
+ .driver = {
+ .name = "IXP4XX-NAND-Flash",
+ },
+};
+
+static int __init ixp4xx_nand_flash_init(void)
+{
+ return platform_driver_register(&ixp4xx_nand_flash_driver);
+}
+
+static void __exit ixp4xx_nand_flash_exit(void)
+{
+ platform_driver_unregister(&ixp4xx_nand_flash_driver);
+}
+
+module_init(ixp4xx_nand_flash_init);
+module_exit(ixp4xx_nand_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on "
+ "IXP4xx-based platform");
+
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 10:33 ` Ruslan V. Sushko
@ 2007-04-24 10:38 ` Lennert Buytenhek
2007-04-24 10:46 ` Ruslan V. Sushko
0 siblings, 1 reply; 14+ messages in thread
From: Lennert Buytenhek @ 2007-04-24 10:38 UTC (permalink / raw)
To: Ruslan V. Sushko; +Cc: linux-mtd
On Tue, Apr 24, 2007 at 02:33:40PM +0400, Ruslan V. Sushko wrote:
> The patch adds glue logic to support MTD for NAND flash devices on
> Intel IXP4xx based platform
Hmm, the IXP4xx doesn't have an on-chip NAND controller, does it?
Is this for NAND flashes connected to the expansion bus? Maybe we
need something a la physmap for NAND flashes..
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 10:38 ` Lennert Buytenhek
@ 2007-04-24 10:46 ` Ruslan V. Sushko
2007-04-24 10:49 ` Lennert Buytenhek
0 siblings, 1 reply; 14+ messages in thread
From: Ruslan V. Sushko @ 2007-04-24 10:46 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: linux-mtd
Lennert Buytenhek wrote:
> On Tue, Apr 24, 2007 at 02:33:40PM +0400, Ruslan V. Sushko wrote:
>
>
>> The patch adds glue logic to support MTD for NAND flash devices on
>> Intel IXP4xx based platform
>>
>
> Hmm, the IXP4xx doesn't have an on-chip NAND controller, does it?
> Is this for NAND flashes connected to the expansion bus? Maybe we
> need something a la physmap for NAND flashes..
>
Yes, It's true the NAND flash is connected to expansion bus. The driver
has two parts: The common glue logic submitted here and the platform
specific (evaluation board) definition submitted to
http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4323/2
All maps defined in last patch
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 10:46 ` Ruslan V. Sushko
@ 2007-04-24 10:49 ` Lennert Buytenhek
2007-04-24 10:53 ` Vitaly Wool
0 siblings, 1 reply; 14+ messages in thread
From: Lennert Buytenhek @ 2007-04-24 10:49 UTC (permalink / raw)
To: Ruslan V. Sushko; +Cc: linux-mtd
On Tue, Apr 24, 2007 at 02:46:07PM +0400, Ruslan V. Sushko wrote:
> >>The patch adds glue logic to support MTD for NAND flash devices on
> >>Intel IXP4xx based platform
> >
> >Hmm, the IXP4xx doesn't have an on-chip NAND controller, does it?
> >Is this for NAND flashes connected to the expansion bus? Maybe we
> >need something a la physmap for NAND flashes..
>
> Yes, It's true the NAND flash is connected to expansion bus. The driver
> has two parts: The common glue logic submitted here and the platform
> specific (evaluation board) definition submitted to
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4323/2
> All maps defined in last patch
I wonder how much sense it makes to call this mtd driver "the
ixp4xx NAND flash driver" if there's hardly anything ixp4xx-specific
in it.
For that matter, I wonder how much sense it makes to submit a
separate NAND driver for every ARM SoC. For NOR flashes we have
physmap, we should have something similar for NAND.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 10:49 ` Lennert Buytenhek
@ 2007-04-24 10:53 ` Vitaly Wool
2007-04-24 11:01 ` Lennert Buytenhek
0 siblings, 1 reply; 14+ messages in thread
From: Vitaly Wool @ 2007-04-24 10:53 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: linux-mtd, Ruslan V. Sushko
On 4/24/07, Lennert Buytenhek <buytenh@wantstofly.org> wrote:
> I wonder how much sense it makes to call this mtd driver "the
> ixp4xx NAND flash driver" if there's hardly anything ixp4xx-specific
> in it.
>
> For that matter, I wonder how much sense it makes to submit a
> separate NAND driver for every ARM SoC. For NOR flashes we have
> physmap, we should have something similar for NAND.
It won't do for all the cases, but for the drivers where only cmd_ctrl
differs that might really make sense.
Vitaly
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 10:53 ` Vitaly Wool
@ 2007-04-24 11:01 ` Lennert Buytenhek
2007-04-24 11:10 ` Ruslan V. Sushko
2007-04-24 11:21 ` Vitaly Wool
0 siblings, 2 replies; 14+ messages in thread
From: Lennert Buytenhek @ 2007-04-24 11:01 UTC (permalink / raw)
To: Vitaly Wool; +Cc: linux-mtd, Ruslan V. Sushko
On Tue, Apr 24, 2007 at 02:53:41PM +0400, Vitaly Wool wrote:
> >I wonder how much sense it makes to call this mtd driver "the
> >ixp4xx NAND flash driver" if there's hardly anything ixp4xx-specific
> >in it.
> >
> >For that matter, I wonder how much sense it makes to submit a
> >separate NAND driver for every ARM SoC. For NOR flashes we have
> >physmap, we should have something similar for NAND.
>
> It won't do for all the cases, but for the drivers where only cmd_ctrl
> differs that might really make sense.
Yes, exactly. For a unified NAND driver, you can just assume that the
data register will be memory-mapped. This is probably true in 99% of
the cases. In cases where this isn't true, people can still write their
own driver.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 11:01 ` Lennert Buytenhek
@ 2007-04-24 11:10 ` Ruslan V. Sushko
2007-04-24 11:21 ` Vitaly Wool
1 sibling, 0 replies; 14+ messages in thread
From: Ruslan V. Sushko @ 2007-04-24 11:10 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: linux-mtd, Vitaly Wool
Lennert Buytenhek wrote:
> Yes, exactly. For a unified NAND driver, you can just assume that the
> data register will be memory-mapped. This is probably true in 99% of
> the cases. In cases where this isn't true, people can still write their
> own driver.
>
Seem it should be ok for most drivers. In this case we need to drive
Chip Select signal "manually" through(Not all signal connected to
expansion bus). At the same time different vendor make create CS in
different way.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] NAND Flash support for Intel IXP4xx platform
2007-04-24 11:01 ` Lennert Buytenhek
2007-04-24 11:10 ` Ruslan V. Sushko
@ 2007-04-24 11:21 ` Vitaly Wool
1 sibling, 0 replies; 14+ messages in thread
From: Vitaly Wool @ 2007-04-24 11:21 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: linux-mtd, Ruslan V. Sushko
On 4/24/07, Lennert Buytenhek <buytenh@wantstofly.org> wrote:
> > >For that matter, I wonder how much sense it makes to submit a
> > >separate NAND driver for every ARM SoC. For NOR flashes we have
> > >physmap, we should have something similar for NAND.
> >
> > It won't do for all the cases, but for the drivers where only cmd_ctrl
> > differs that might really make sense.
>
> Yes, exactly. For a unified NAND driver, you can just assume that the
> data register will be memory-mapped. This is probably true in 99% of
> the cases. In cases where this isn't true, people can still write their
> own driver.
Yes, but the "write your own" case will also be applicable to the
cases where the controller has HW ECC capabilities, for instance.
Vitaly
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2007-04-24 11:21 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-19 10:29 [PATCH] NAND Flash support for Intel IXP4xx platform Ruslan V. Sushko
2007-04-20 8:25 ` Vitaly Wool
2007-04-20 14:16 ` Ruslan V. Sushko
2007-04-24 7:21 ` Vitaly Wool
2007-04-24 8:29 ` Ruslan V. Sushko
2007-04-24 8:34 ` Vitaly Wool
2007-04-24 10:33 ` Ruslan V. Sushko
2007-04-24 10:38 ` Lennert Buytenhek
2007-04-24 10:46 ` Ruslan V. Sushko
2007-04-24 10:49 ` Lennert Buytenhek
2007-04-24 10:53 ` Vitaly Wool
2007-04-24 11:01 ` Lennert Buytenhek
2007-04-24 11:10 ` Ruslan V. Sushko
2007-04-24 11:21 ` Vitaly Wool
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox