diff for duplicates of <200710270653.32459.sr@denx.de> diff --git a/a/1.txt b/N1/1.txt index 85deaa6..601a427 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -2,7 +2,8 @@ Hi Valentine, On Friday 26 October 2007, Valentine Barshak wrote: > This adds device-tree aware PowerPC 44x NDFC (NAND Flash Controller) -> driver. The code is based on the original ndfc.c driver by Thomas Gleixner. +> driver. The code is based on the original ndfc.c driver by Thomas Gleixne= +r. > The major difference is that here we try to handle all chips found as one > mtd device instead of having a separate one on each chip. > The partition handling code is based on the physmap_of one. @@ -16,60 +17,77 @@ On Friday 26 October 2007, Valentine Barshak wrote: Are you sure you have the Signed-off-by from Thomas already on this? > --- -> drivers/mtd/nand/Kconfig | 7 -> drivers/mtd/nand/Makefile | 1 -> drivers/mtd/nand/ndfc_of.c | 449 -> +++++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/ndfc.h | -> 4 -> 4 files changed, 461 insertions(+) +> =A0drivers/mtd/nand/Kconfig =A0 | =A0 =A07 +> =A0drivers/mtd/nand/Makefile =A0| =A0 =A01 +> =A0drivers/mtd/nand/ndfc_of.c | =A0449 +> +++++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/ndfc.h = +=A0 | +> =A0 =A04 +> =A04 files changed, 461 insertions(+) > > diff -pruN linux-2.6.orig/drivers/mtd/nand/Kconfig > linux-2.6/drivers/mtd/nand/Kconfig --- -> linux-2.6.orig/drivers/mtd/nand/Kconfig 2007-10-25 19:20:05.000000000 -> +0400 +++ linux-2.6/drivers/mtd/nand/Kconfig 2007-10-26 16:16:20.000000000 +> linux-2.6.orig/drivers/mtd/nand/Kconfig=A0=A0=A0=A0=A02007-10-25 19:20:05= +=2E000000000 +> +0400 +++ linux-2.6/drivers/mtd/nand/Kconfig=A0=A02007-10-26 16:16:20.000= +000000 > +0400 @@ -158,6 +158,13 @@ config MTD_NAND_NDFC -> help -> NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs -> +> =A0=A0=A0=A0=A0=A0=A0=A0help +> =A0=A0=A0=A0=A0=A0=A0=A0 NDFC Nand Flash Controllers are integrated in IB= +M/AMCC's 4xx SoCs +> =A0 > +config MTD_NAND_NDFC_OF -> + tristate "NDFC OF Nand Flash Controller" -> + depends on 44x -> + select MTD_NAND_ECC_SMC -> + help -> + NDFC OF Nand Flash Controllers are integrated in PowerPC44x SoCs -> + -> config MTD_NAND_S3C2410_CLKSTOP -> bool "S3C2410 NAND IDLE clock stop" -> depends on MTD_NAND_S3C2410 +> +=A0=A0=A0=A0=A0=A0=A0tristate "NDFC OF Nand Flash Controller" +> +=A0=A0=A0=A0=A0=A0=A0depends on 44x +> +=A0=A0=A0=A0=A0=A0=A0select MTD_NAND_ECC_SMC +> +=A0=A0=A0=A0=A0=A0=A0help +> +=A0=A0=A0=A0=A0=A0=A0 NDFC OF Nand Flash Controllers are integrated in P= +owerPC44x SoCs +> + +> =A0config MTD_NAND_S3C2410_CLKSTOP +> =A0=A0=A0=A0=A0=A0=A0=A0bool "S3C2410 NAND IDLE clock stop" +> =A0=A0=A0=A0=A0=A0=A0=A0depends on MTD_NAND_S3C2410 > diff -pruN linux-2.6.orig/drivers/mtd/nand/Makefile > linux-2.6/drivers/mtd/nand/Makefile --- -> linux-2.6.orig/drivers/mtd/nand/Makefile 2007-10-25 19:20:05.000000000 -> +0400 +++ linux-2.6/drivers/mtd/nand/Makefile 2007-10-26 16:16:20.000000000 -> +0400 @@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_NAND_TS7250) += ts7250 -> obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o -> obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o -> obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o -> +obj-$(CONFIG_MTD_NAND_NDFC_OF) += ndfc_of.o -> obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o -> obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o -> obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o +> linux-2.6.orig/drivers/mtd/nand/Makefile=A0=A0=A0=A02007-10-25 19:20:05.0= +00000000 +> +0400 +++ linux-2.6/drivers/mtd/nand/Makefile=A02007-10-26 16:16:20.00000= +0000 +> +0400 @@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_NAND_TS7250)=A0=A0=A0=A0=A0=A0= +=A0=A0=A0+=3D ts7250 +> =A0obj-$(CONFIG_MTD_NAND_NANDSIM)=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D nandsim.o +> =A0obj-$(CONFIG_MTD_NAND_CS553X)=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D cs553x= +_nand.o +> =A0obj-$(CONFIG_MTD_NAND_NDFC)=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D nd= +fc.o +> +obj-$(CONFIG_MTD_NAND_NDFC_OF)=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D ndfc_of.o +> =A0obj-$(CONFIG_MTD_NAND_AT91)=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D at= +91_nand.o +> =A0obj-$(CONFIG_MTD_NAND_CM_X270)=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D cmx270_n= +and.o +> =A0obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)=A0=A0=A0+=3D excite_nandflash.o > diff -pruN linux-2.6.orig/drivers/mtd/nand/ndfc_of.c > linux-2.6/drivers/mtd/nand/ndfc_of.c --- -> linux-2.6.orig/drivers/mtd/nand/ndfc_of.c 1970-01-01 03:00:00.000000000 -> +0300 +++ linux-2.6/drivers/mtd/nand/ndfc_of.c 2007-10-26 +> linux-2.6.orig/drivers/mtd/nand/ndfc_of.c=A0=A0=A01970-01-01 03:00:00.000= +000000 +> +0300 +++ linux-2.6/drivers/mtd/nand/ndfc_of.c=A0=A0=A0=A0=A0=A0=A0=A0200= +7-10-26 > 17:28:57.000000000 +0400 @@ -0,0 +1,449 @@ > +/* -> + * PowerPC 44x NDFC (NanD Flash Controller) driver -> + * with OF device tree support. +> + * =A0PowerPC 44x NDFC (NanD Flash Controller) driver +> + * =A0with OF device tree support. > + * -> + * Based on the original ndfc driver by Thomas Gleixner +> + * =A0Based on the original ndfc driver by Thomas Gleixner > + * -> + * Copyright 2006 IBM +> + * =A0Copyright 2006 IBM > + * -> + * 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. +> + * =A0This program is free software; you can redistribute=A0=A0=A0=A0=A0= +=A0=A0=A0 it and/or +> modify it + * =A0under =A0the terms of=A0=A0=A0=A0=A0=A0=A0=A0 the GNU Ge= +neral =A0Public License +> as published by the + * =A0Free Software Foundation; =A0either version 2 = +of +> the=A0License, or (at your + * =A0option) any later version. > + * > + */ > +#include <linux/module.h> @@ -85,16 +103,20 @@ Are you sure you have the Signed-off-by from Thomas already on this? > + > + > +struct of_ndfc { -> + __iomem void *base; -> + struct resource *res; -> + unsigned bank_width; -> + unsigned chip_cnt; -> + unsigned char chip_map[NDFC_MAX_BANKS]; -> + struct nand_hw_control control; -> + struct nand_chip chip; -> + struct mtd_info mtd; +> +=A0=A0=A0=A0=A0=A0=A0__iomem void=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0*ba= +se; +> +=A0=A0=A0=A0=A0=A0=A0struct resource=A0=A0=A0=A0=A0=A0=A0=A0=A0*res; +> +=A0=A0=A0=A0=A0=A0=A0unsigned=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= +=A0=A0bank_width; +> +=A0=A0=A0=A0=A0=A0=A0unsigned =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= +=A0chip_cnt; +> +=A0=A0=A0=A0=A0=A0=A0unsigned char=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0chip_= +map[NDFC_MAX_BANKS]; +> +=A0=A0=A0=A0=A0=A0=A0struct nand_hw_control=A0=A0control; +> +=A0=A0=A0=A0=A0=A0=A0struct nand_chip=A0=A0=A0=A0=A0=A0=A0=A0chip; +> +=A0=A0=A0=A0=A0=A0=A0struct mtd_info=A0=A0=A0=A0=A0=A0=A0=A0=A0mtd; > +#ifdef CONFIG_MTD_PARTITIONS -> + struct mtd_partition *parts; +> +=A0=A0=A0=A0=A0=A0=A0struct mtd_partition=A0=A0=A0=A0*parts; > +#endif > +}; > + @@ -103,7 +125,8 @@ Are you sure you have the Signed-off-by from Thomas already on this? > + return __raw_readl(ndfc->base + off); > +} > + -> +static inline void ndfc_raw_writel(struct of_ndfc *ndfc, u32 off, u32 val) +> +static inline void ndfc_raw_writel(struct of_ndfc *ndfc, u32 off, u32 va= +l) > +{ > + __raw_writel(val, ndfc->base + off); > +} @@ -115,25 +138,25 @@ Are you sure you have the Signed-off-by from Thomas already on this? > + > +static void ndfc_select_chip(struct mtd_info *mtd, int chip) > +{ -> + struct nand_chip *this = mtd->priv; -> + struct of_ndfc *ndfc = this->priv; +> + struct nand_chip *this =3D mtd->priv; +> + struct of_ndfc *ndfc =3D this->priv; > + uint32_t ccr; > + -> + ccr = ndfc_raw_readl(ndfc, NDFC_CCR); -> + if ((chip >= 0) && (chip < ndfc->chip_cnt)) { -> + ccr &= ~NDFC_CCR_BS_MASK; -> + ccr |= NDFC_CCR_BS(ndfc->chip_map[chip]); +> + ccr =3D ndfc_raw_readl(ndfc, NDFC_CCR); +> + if ((chip >=3D 0) && (chip < ndfc->chip_cnt)) { +> + ccr &=3D ~NDFC_CCR_BS_MASK; +> + ccr |=3D NDFC_CCR_BS(ndfc->chip_map[chip]); > + } else -> + ccr |= NDFC_CCR_RESET_CE; +> + ccr |=3D NDFC_CCR_RESET_CE; > + ndfc_raw_writel(ndfc, NDFC_CCR, ccr); > +} > + > +static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int > ctrl) +{ -> + struct nand_chip *this = mtd->priv; -> + struct of_ndfc *ndfc = this->priv; +> + struct nand_chip *this =3D mtd->priv; +> + struct of_ndfc *ndfc =3D this->priv; > + -> + if (cmd == NAND_CMD_NONE) +> + if (cmd =3D=3D NAND_CMD_NONE) > + return; > + > + if (ctrl & NAND_CLE) @@ -144,8 +167,8 @@ Are you sure you have the Signed-off-by from Thomas already on this? > + > +static int ndfc_ready(struct mtd_info *mtd) > +{ -> + struct nand_chip *this = mtd->priv; -> + struct of_ndfc *ndfc = this->priv; +> + struct nand_chip *this =3D mtd->priv; +> + struct of_ndfc *ndfc =3D this->priv; > + > + return ndfc_raw_readl(ndfc, NDFC_STAT) & NDFC_STAT_IS_READY; > +} @@ -153,15 +176,16 @@ Are you sure you have the Signed-off-by from Thomas already on this? > +static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) > +{ > + uint32_t ccr; -> + struct nand_chip *this = mtd->priv; -> + struct of_ndfc *ndfc = this->priv; +> + struct nand_chip *this =3D mtd->priv; +> + struct of_ndfc *ndfc =3D this->priv; > + -> + ccr = ndfc_raw_readl(ndfc, NDFC_CCR); -> + ccr |= NDFC_CCR_RESET_ECC; +> + ccr =3D ndfc_raw_readl(ndfc, NDFC_CCR); +> + ccr |=3D NDFC_CCR_RESET_ECC; > + ndfc_raw_writel(ndfc, NDFC_CCR, ccr); > + wmb(); -I suspect that when we use the in_be32() and friends functions for IO access, +I suspect that when we use the in_be32() and friends functions for IO acces= +s,=20 the memory-barriers can go away. > +} @@ -171,18 +195,18 @@ the memory-barriers can go away. > + const u_char *dat, u_char *ecc_code) > +{ > + uint32_t ecc; -> + struct nand_chip *this = mtd->priv; -> + struct of_ndfc *ndfc = this->priv; -> + uint8_t *p = (uint8_t *)&ecc; +> + struct nand_chip *this =3D mtd->priv; +> + struct of_ndfc *ndfc =3D this->priv; +> + uint8_t *p =3D (uint8_t *)&ecc; > + > + wmb(); Same here. -> + ecc = ndfc_raw_readl(ndfc, NDFC_ECC); -> + ecc_code[0] = p[1]; -> + ecc_code[1] = p[2]; -> + ecc_code[2] = p[3]; +> + ecc =3D ndfc_raw_readl(ndfc, NDFC_ECC); +> + ecc_code[0] =3D p[1]; +> + ecc_code[1] =3D p[2]; +> + ecc_code[2] =3D p[3]; > + > + return 0; > +} @@ -197,32 +221,32 @@ Same here. > + */ > +static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) > +{ -> + struct nand_chip *this = mtd->priv; -> + struct of_ndfc *ndfc = this->priv; -> + uint32_t *p = (uint32_t *) buf; +> + struct nand_chip *this =3D mtd->priv; +> + struct of_ndfc *ndfc =3D this->priv; +> + uint32_t *p =3D (uint32_t *) buf; > + -> + for(;len > 0; len -= 4) -> + *p++ = ndfc_raw_readl(ndfc, NDFC_DATA); +> + for(;len > 0; len -=3D 4) +> + *p++ =3D ndfc_raw_readl(ndfc, NDFC_DATA); > +} > + > +static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int > len) +{ -> + struct nand_chip *this = mtd->priv; -> + struct of_ndfc *ndfc = this->priv; -> + uint32_t *p = (uint32_t *) buf; +> + struct nand_chip *this =3D mtd->priv; +> + struct of_ndfc *ndfc =3D this->priv; +> + uint32_t *p =3D (uint32_t *) buf; > + -> + for(;len > 0; len -= 4) +> + for(;len > 0; len -=3D 4) > + ndfc_raw_writel(ndfc, NDFC_DATA, *p++); > +} > + > +static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int > len) +{ -> + struct nand_chip *this = mtd->priv; -> + struct of_ndfc *ndfc = this->priv; -> + uint32_t *p = (uint32_t *) buf; +> + struct nand_chip *this =3D mtd->priv; +> + struct of_ndfc *ndfc =3D this->priv; +> + uint32_t *p =3D (uint32_t *) buf; > + -> + for(;len > 0; len -= 4) -> + if (*p++ != ndfc_raw_readl(ndfc, NDFC_DATA)) +> + for(;len > 0; len -=3D 4) +> + if (*p++ !=3D ndfc_raw_readl(ndfc, NDFC_DATA)) > + return -EFAULT; > + return 0; > +} @@ -232,27 +256,27 @@ Same here. > +static void ndfc_chip_init(struct nand_chip *chip, > + struct of_ndfc *ndfc) > +{ -> + chip->IO_ADDR_R = ndfc->base + NDFC_DATA; -> + chip->IO_ADDR_W = ndfc->base + NDFC_DATA; -> + chip->cmd_ctrl = ndfc_hwcontrol; -> + chip->dev_ready = ndfc_ready; -> + chip->select_chip = ndfc_select_chip; -> + chip->chip_delay = 50; -> + chip->priv = ndfc; -> + if (ndfc->bank_width == 2) -> + chip->options |= NAND_BUSWIDTH_16; -> + chip->controller = &ndfc->control; -> + chip->read_buf = ndfc_read_buf; -> + chip->write_buf = ndfc_write_buf; -> + chip->verify_buf = ndfc_verify_buf; -> + chip->ecc.correct = nand_correct_data; -> + chip->ecc.hwctl = ndfc_enable_hwecc; -> + chip->ecc.calculate = ndfc_calculate_ecc; -> + chip->ecc.mode = NAND_ECC_HW; -> + chip->ecc.size = 256; -> + chip->ecc.bytes = 3; -> + ndfc->mtd.priv = chip; -> + ndfc->mtd.owner = THIS_MODULE; +> + chip->IO_ADDR_R =3D ndfc->base + NDFC_DATA; +> + chip->IO_ADDR_W =3D ndfc->base + NDFC_DATA; +> + chip->cmd_ctrl =3D ndfc_hwcontrol; +> + chip->dev_ready =3D ndfc_ready; +> + chip->select_chip =3D ndfc_select_chip; +> + chip->chip_delay =3D 50; +> + chip->priv =3D ndfc; +> + if (ndfc->bank_width =3D=3D 2) +> + chip->options |=3D NAND_BUSWIDTH_16; +> + chip->controller =3D &ndfc->control; +> + chip->read_buf =3D ndfc_read_buf; +> + chip->write_buf =3D ndfc_write_buf; +> + chip->verify_buf =3D ndfc_verify_buf; +> + chip->ecc.correct =3D nand_correct_data; +> + chip->ecc.hwctl =3D ndfc_enable_hwecc; +> + chip->ecc.calculate =3D ndfc_calculate_ecc; +> + chip->ecc.mode =3D NAND_ECC_HW; +> + chip->ecc.size =3D 256; +> + chip->ecc.bytes =3D 3; +> + ndfc->mtd.priv =3D chip; +> + ndfc->mtd.owner =3D THIS_MODULE; > +} > + > + @@ -264,13 +288,13 @@ Same here. > +{ > + const char *partname; > + static const char *part_probe_types[] -> + = { "cmdlinepart", "RedBoot", NULL }; -> + struct device_node *dp = dev->node, *pp; +> + =3D { "cmdlinepart", "RedBoot", NULL }; +> + struct device_node *dp =3D dev->node, *pp; > + int nr_parts, i; > + > + /* First look for RedBoot table or partitions on the command > + * line, these take precedence over device tree information */ -> + nr_parts = parse_mtd_partitions(&ndfc->mtd, part_probe_types, +> + nr_parts =3D parse_mtd_partitions(&ndfc->mtd, part_probe_types, > + &ndfc->parts, 0); > + if (nr_parts > 0) { > + add_mtd_partitions(&ndfc->mtd, ndfc->parts, nr_parts); @@ -278,47 +302,48 @@ Same here. > + } > + > + /* First count the subnodes */ -> + nr_parts = 0; -> + for (pp = dp->child; pp; pp = pp->sibling) +> + nr_parts =3D 0; +> + for (pp =3D dp->child; pp; pp =3D pp->sibling) > + nr_parts++; > + -> + if (nr_parts == 0) +> + if (nr_parts =3D=3D 0) > + return 0; > + -> + ndfc->parts = kzalloc(nr_parts * sizeof(*ndfc->parts), +> + ndfc->parts =3D kzalloc(nr_parts * sizeof(*ndfc->parts), > + GFP_KERNEL); > + if (!ndfc->parts) > + return -ENOMEM; > + -> + for (pp = dp->child, i = 0; pp; pp = pp->sibling, i++) { +> + for (pp =3D dp->child, i =3D 0; pp; pp =3D pp->sibling, i++) { > + const u32 *reg; > + int len; > + -> + reg = of_get_property(pp, "reg", &len); -> + if (!reg || (len != 2*sizeof(u32))) { +> + reg =3D of_get_property(pp, "reg", &len); +> + if (!reg || (len !=3D 2*sizeof(u32))) { > + dev_err(&dev->dev, "Invalid 'reg' on %s\n", > + dp->full_name); > + kfree(ndfc->parts); -> + ndfc->parts = NULL; +> + ndfc->parts =3D NULL; > + return -EINVAL; > + } -> + ndfc->parts[i].offset = reg[0]; -> + ndfc->parts[i].size = reg[1]; +> + ndfc->parts[i].offset =3D reg[0]; +> + ndfc->parts[i].size =3D reg[1]; > + -> + partname = of_get_property(pp, "label", &len); +> + partname =3D of_get_property(pp, "label", &len); > + if (!partname) -> + partname = of_get_property(pp, "name", &len); -> + ndfc->parts[i].name = (char *)partname; +> + partname =3D of_get_property(pp, "name", &len); +> + ndfc->parts[i].name =3D (char *)partname; > + > + if (of_get_property(pp, "read-only", &len)) -> + ndfc->parts[i].mask_flags = MTD_WRITEABLE; +> + ndfc->parts[i].mask_flags =3D MTD_WRITEABLE; > + } > + > + return nr_parts; > +} -This parse_partition code looks very much like the code in the physmap_of -driver. I think it would be a good idea not to duplicate this code, but to +This parse_partition code looks very much like the code in the physmap_of=20 +driver. I think it would be a good idea not to duplicate this code, but to= +=20 extract it and use one version in both drivers. > +#else /* MTD_PARTITIONS */ @@ -331,7 +356,7 @@ extract it and use one version in both drivers. > +{ > + struct of_ndfc *ndfc; > + -> + ndfc = dev_get_drvdata(&dev->dev); +> + ndfc =3D dev_get_drvdata(&dev->dev); > + if (!ndfc) > + return 0; > + @@ -359,7 +384,8 @@ extract it and use one version in both drivers. > +} > + > + -> +static int __devinit ndfc_map_banks(struct of_ndfc *ndfc, const u32 *mask) +> +static int __devinit ndfc_map_banks(struct of_ndfc *ndfc, const u32 *mas= +k) > +{ > + unsigned cnt, i, tmp; > + uint32_t bcr; @@ -368,25 +394,25 @@ extract it and use one version in both drivers. > + return -EINVAL; > + > + /* Disable all banks */ -> + for (cnt = 0; cnt < NDFC_MAX_BANKS; cnt++) { +> + for (cnt =3D 0; cnt < NDFC_MAX_BANKS; cnt++) { > + ndfc_raw_writel(ndfc, NDFC_BCFG0 + (cnt << 2), 0); > + } > + > + /* Enable bank and set default RE/WE/CE timings */ -> + bcr = NDFC_BxCFG_EN | NDFC_BxCFG_RR(2) | NDFC_BxCFG_RWH(2) | +> + bcr =3D NDFC_BxCFG_EN | NDFC_BxCFG_RR(2) | NDFC_BxCFG_RWH(2) | > + NDFC_BxCFG_RWP(2) | NDFC_BxCFG_CRW(2); -> + if (ndfc->bank_width == 2) -> + bcr |= NDFC_BxCFG_SZ_16BIT; +> + if (ndfc->bank_width =3D=3D 2) +> + bcr |=3D NDFC_BxCFG_SZ_16BIT; > + -> + cnt = 0; -> + tmp = *mask; -> + while ((i = ffs(tmp)) && (cnt < NDFC_MAX_BANKS)) { +> + cnt =3D 0; +> + tmp =3D *mask; +> + while ((i =3D ffs(tmp)) && (cnt < NDFC_MAX_BANKS)) { > + i--; -> + tmp &= ~(1 << i); -> + ndfc->chip_map[cnt++] = i; +> + tmp &=3D ~(1 << i); +> + ndfc->chip_map[cnt++] =3D i; > + ndfc_raw_writel(ndfc, NDFC_BCFG0 + (i << 2), bcr); > + } -> + ndfc->chip_cnt = cnt; +> + ndfc->chip_cnt =3D cnt; > + return cnt; > +} > + @@ -394,14 +420,14 @@ extract it and use one version in both drivers. > +static int __devinit of_ndfc_probe(struct of_device *dev, > + const struct of_device_id *match) > +{ -> + struct device_node *dp = dev->node; +> + struct device_node *dp =3D dev->node; > + struct resource res; > + struct of_ndfc *ndfc; > + const u32 *prop; > + resource_size_t rlen; > + int err; > + -> + err = -ENXIO; +> + err =3D -ENXIO; > + if (of_address_to_resource(dp, 0, &res)) { > + dev_err(&dev->dev, "can't get IO address from device tree\n"); > + goto err_out; @@ -410,36 +436,36 @@ extract it and use one version in both drivers. > + dev_dbg(&dev->dev, "regs: %.8llx-%.8llx\n", > + (unsigned long long)res.start, (unsigned long long)res.end); > + -> + ndfc = kzalloc(sizeof(struct of_ndfc), GFP_KERNEL); +> + ndfc =3D kzalloc(sizeof(struct of_ndfc), GFP_KERNEL); > + if (!ndfc) { -> + err = -ENOMEM; +> + err =3D -ENOMEM; > + goto err_out; > + } > + -> + rlen = res.end - res.start + 1; -> + ndfc->res = request_mem_region(res.start, rlen, dev->dev.bus_id); +> + rlen =3D res.end - res.start + 1; +> + ndfc->res =3D request_mem_region(res.start, rlen, dev->dev.bus_id); > + if (!ndfc->res) { -> + err = -EBUSY; +> + err =3D -EBUSY; > + goto err_free_out; > + } > + -> + ndfc->base = ioremap(res.start, rlen); +> + ndfc->base =3D ioremap(res.start, rlen); > + if (!ndfc->base) { -> + err = -ENXIO; +> + err =3D -ENXIO; > + goto err_rel_out; > + } > + > + spin_lock_init(&ndfc->control.lock); > + init_waitqueue_head(&ndfc->control.wq); > + -> + prop = of_get_property(dp, "bank-width", NULL); -> + ndfc->bank_width = ((prop) && (*prop) == 2) ? 2 : 1; +> + prop =3D of_get_property(dp, "bank-width", NULL); +> + ndfc->bank_width =3D ((prop) && (*prop) =3D=3D 2) ? 2 : 1; > + -> + prop = of_get_property(dp, "bank-mask", NULL); -> + err = ndfc_map_banks(ndfc, prop); -> + if (err <= 0) { +> + prop =3D of_get_property(dp, "bank-mask", NULL); +> + err =3D ndfc_map_banks(ndfc, prop); +> + if (err <=3D 0) { > + dev_err(&dev->dev, "no banks found\n"); -> + err = -ENODEV; +> + err =3D -ENODEV; > + goto err_unmap_out; > + } > + @@ -449,21 +475,21 @@ extract it and use one version in both drivers. > + dev_info(&dev->dev, "NDFC driver initialized. Chip-Rev: 0x%08x\n", > + ndfc_raw_readl(ndfc, NDFC_REVID)); > + -> + err = nand_scan_ident(&ndfc->mtd, ndfc->chip_cnt); +> + err =3D nand_scan_ident(&ndfc->mtd, ndfc->chip_cnt); > + if (err) > + goto err_dat_out; > + -> + if ((ndfc->mtd.writesize != 2048) && (ndfc->mtd.writesize != 512)) { +> + if ((ndfc->mtd.writesize !=3D 2048) && (ndfc->mtd.writesize !=3D 512)) { > + dev_err(&dev->dev, "unexpected NAND flash writesize %d", > + ndfc->mtd.writesize); > + goto err_dat_out; > + } > + -> + err = nand_scan_tail(&ndfc->mtd); +> + err =3D nand_scan_tail(&ndfc->mtd); > + if (err) > + goto err_dat_out; > + -> + err = parse_partitions(ndfc, dev); +> + err =3D parse_partitions(ndfc, dev); > + if (err < 0) > + goto err_dat_out; > + @@ -487,19 +513,19 @@ extract it and use one version in both drivers. > + return err; > +} > + -> +static struct of_device_id of_ndfc_match[] = { +> +static struct of_device_id of_ndfc_match[] =3D { > + { -> + .compatible = "ibm,ndfc", +> + .compatible =3D "ibm,ndfc", > + }, > + { }, > +}; > +MODULE_DEVICE_TABLE(of, of_ndfc_match); > + -> +static struct of_platform_driver of_ndfc_driver = { -> + .name = "of-ndfc", -> + .match_table = of_ndfc_match, -> + .probe = of_ndfc_probe, -> + .remove = of_ndfc_remove, +> +static struct of_platform_driver of_ndfc_driver =3D { +> + .name =3D "of-ndfc", +> + .match_table =3D of_ndfc_match, +> + .probe =3D of_ndfc_probe, +> + .remove =3D of_ndfc_remove, > +}; > + > +static int __init of_ndfc_init(void) @@ -521,7 +547,8 @@ extract it and use one version in both drivers. > +MODULE_DESCRIPTION("OF driver for NDFC"); > diff -pruN linux-2.6.orig/include/linux/mtd/ndfc.h > linux-2.6/include/linux/mtd/ndfc.h --- -> linux-2.6.orig/include/linux/mtd/ndfc.h 2007-10-25 19:20:42.000000000 +0400 +> linux-2.6.orig/include/linux/mtd/ndfc.h 2007-10-25 19:20:42.000000000 +04= +00 > +++ linux-2.6/include/linux/mtd/ndfc.h 2007-10-26 16:19:42.000000000 +0400 > @@ -52,6 +52,10 @@ > #define NDFC_BxCFG_SZ_MASK 0x08000000 /* Bank Size */ diff --git a/a/content_digest b/N1/content_digest index d8a16ff..255ae17 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -5,15 +5,15 @@ "To\0Valentine Barshak <vbarshak@ru.mvista.com>\0" "Cc\0linuxppc-dev@ozlabs.org" tglx@linutronix.de - linux-mtd@lists.infradead.org - " Josh Boyer <jwboyer@gmail.com>\0" + " linux-mtd@lists.infradead.org\0" "\00:1\0" "b\0" "Hi Valentine,\n" "\n" "On Friday 26 October 2007, Valentine Barshak wrote:\n" "> This adds device-tree aware PowerPC 44x NDFC (NAND Flash Controller)\n" - "> driver. The code is based on the original ndfc.c driver by Thomas Gleixner.\n" + "> driver. The code is based on the original ndfc.c driver by Thomas Gleixne=\n" + "r.\n" "> The major difference is that here we try to handle all chips found as one\n" "> mtd device instead of having a separate one on each chip.\n" "> The partition handling code is based on the physmap_of one.\n" @@ -27,60 +27,77 @@ "Are you sure you have the Signed-off-by from Thomas already on this?\n" "\n" "> ---\n" - "> \302\240drivers/mtd/nand/Kconfig \302\240 | \302\240 \302\2407\n" - "> \302\240drivers/mtd/nand/Makefile \302\240| \302\240 \302\2401\n" - "> \302\240drivers/mtd/nand/ndfc_of.c | \302\240449\n" - "> +++++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/ndfc.h \302\240 |\n" - "> \302\240 \302\2404\n" - "> \302\2404 files changed, 461 insertions(+)\n" + "> =A0drivers/mtd/nand/Kconfig =A0 | =A0 =A07\n" + "> =A0drivers/mtd/nand/Makefile =A0| =A0 =A01\n" + "> =A0drivers/mtd/nand/ndfc_of.c | =A0449\n" + "> +++++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/ndfc.h =\n" + "=A0 |\n" + "> =A0 =A04\n" + "> =A04 files changed, 461 insertions(+)\n" ">\n" "> diff -pruN linux-2.6.orig/drivers/mtd/nand/Kconfig\n" "> linux-2.6/drivers/mtd/nand/Kconfig ---\n" - "> linux-2.6.orig/drivers/mtd/nand/Kconfig\302\240\302\240\302\240\302\240\302\2402007-10-25 19:20:05.000000000\n" - "> +0400 +++ linux-2.6/drivers/mtd/nand/Kconfig\302\240\302\2402007-10-26 16:16:20.000000000\n" + "> linux-2.6.orig/drivers/mtd/nand/Kconfig=A0=A0=A0=A0=A02007-10-25 19:20:05=\n" + "=2E000000000\n" + "> +0400 +++ linux-2.6/drivers/mtd/nand/Kconfig=A0=A02007-10-26 16:16:20.000=\n" + "000000\n" "> +0400 @@ -158,6 +158,13 @@ config MTD_NAND_NDFC\n" - "> \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240help\n" - "> \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240 NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs\n" - "> \302\240\n" + "> =A0=A0=A0=A0=A0=A0=A0=A0help\n" + "> =A0=A0=A0=A0=A0=A0=A0=A0 NDFC Nand Flash Controllers are integrated in IB=\n" + "M/AMCC's 4xx SoCs\n" + "> =A0\n" "> +config MTD_NAND_NDFC_OF\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240tristate \"NDFC OF Nand Flash Controller\"\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240depends on 44x\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240select MTD_NAND_ECC_SMC\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240help\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240 NDFC OF Nand Flash Controllers are integrated in PowerPC44x SoCs\n" - "> +\n" - "> \302\240config MTD_NAND_S3C2410_CLKSTOP\n" - "> \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240bool \"S3C2410 NAND IDLE clock stop\"\n" - "> \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240depends on MTD_NAND_S3C2410\n" + "> +=A0=A0=A0=A0=A0=A0=A0tristate \"NDFC OF Nand Flash Controller\"\n" + "> +=A0=A0=A0=A0=A0=A0=A0depends on 44x\n" + "> +=A0=A0=A0=A0=A0=A0=A0select MTD_NAND_ECC_SMC\n" + "> +=A0=A0=A0=A0=A0=A0=A0help\n" + "> +=A0=A0=A0=A0=A0=A0=A0 NDFC OF Nand Flash Controllers are integrated in P=\n" + "owerPC44x SoCs\n" + "> +\n" + "> =A0config MTD_NAND_S3C2410_CLKSTOP\n" + "> =A0=A0=A0=A0=A0=A0=A0=A0bool \"S3C2410 NAND IDLE clock stop\"\n" + "> =A0=A0=A0=A0=A0=A0=A0=A0depends on MTD_NAND_S3C2410\n" "> diff -pruN linux-2.6.orig/drivers/mtd/nand/Makefile\n" "> linux-2.6/drivers/mtd/nand/Makefile ---\n" - "> linux-2.6.orig/drivers/mtd/nand/Makefile\302\240\302\240\302\240\302\2402007-10-25 19:20:05.000000000\n" - "> +0400 +++ linux-2.6/drivers/mtd/nand/Makefile\302\2402007-10-26 16:16:20.000000000\n" - "> +0400 @@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_NAND_TS7250)\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240+= ts7250\n" - "> \302\240obj-$(CONFIG_MTD_NAND_NANDSIM)\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240+= nandsim.o\n" - "> \302\240obj-$(CONFIG_MTD_NAND_CS553X)\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240+= cs553x_nand.o\n" - "> \302\240obj-$(CONFIG_MTD_NAND_NDFC)\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240+= ndfc.o\n" - "> +obj-$(CONFIG_MTD_NAND_NDFC_OF)\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240+= ndfc_of.o\n" - "> \302\240obj-$(CONFIG_MTD_NAND_AT91)\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240+= at91_nand.o\n" - "> \302\240obj-$(CONFIG_MTD_NAND_CM_X270)\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240+= cmx270_nand.o\n" - "> \302\240obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)\302\240\302\240\302\240+= excite_nandflash.o\n" + "> linux-2.6.orig/drivers/mtd/nand/Makefile=A0=A0=A0=A02007-10-25 19:20:05.0=\n" + "00000000\n" + "> +0400 +++ linux-2.6/drivers/mtd/nand/Makefile=A02007-10-26 16:16:20.00000=\n" + "0000\n" + "> +0400 @@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_NAND_TS7250)=A0=A0=A0=A0=A0=A0=\n" + "=A0=A0=A0+=3D ts7250\n" + "> =A0obj-$(CONFIG_MTD_NAND_NANDSIM)=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D nandsim.o\n" + "> =A0obj-$(CONFIG_MTD_NAND_CS553X)=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D cs553x=\n" + "_nand.o\n" + "> =A0obj-$(CONFIG_MTD_NAND_NDFC)=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D nd=\n" + "fc.o\n" + "> +obj-$(CONFIG_MTD_NAND_NDFC_OF)=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D ndfc_of.o\n" + "> =A0obj-$(CONFIG_MTD_NAND_AT91)=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D at=\n" + "91_nand.o\n" + "> =A0obj-$(CONFIG_MTD_NAND_CM_X270)=A0=A0=A0=A0=A0=A0=A0=A0=A0+=3D cmx270_n=\n" + "and.o\n" + "> =A0obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)=A0=A0=A0+=3D excite_nandflash.o\n" "> diff -pruN linux-2.6.orig/drivers/mtd/nand/ndfc_of.c\n" "> linux-2.6/drivers/mtd/nand/ndfc_of.c ---\n" - "> linux-2.6.orig/drivers/mtd/nand/ndfc_of.c\302\240\302\240\302\2401970-01-01 03:00:00.000000000\n" - "> +0300 +++ linux-2.6/drivers/mtd/nand/ndfc_of.c\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\2402007-10-26\n" + "> linux-2.6.orig/drivers/mtd/nand/ndfc_of.c=A0=A0=A01970-01-01 03:00:00.000=\n" + "000000\n" + "> +0300 +++ linux-2.6/drivers/mtd/nand/ndfc_of.c=A0=A0=A0=A0=A0=A0=A0=A0200=\n" + "7-10-26\n" "> 17:28:57.000000000 +0400 @@ -0,0 +1,449 @@\n" "> +/*\n" - "> + * \302\240PowerPC 44x NDFC (NanD Flash Controller) driver\n" - "> + * \302\240with OF device tree support.\n" + "> + * =A0PowerPC 44x NDFC (NanD Flash Controller) driver\n" + "> + * =A0with OF device tree support.\n" "> + *\n" - "> + * \302\240Based on the original ndfc driver by Thomas Gleixner\n" + "> + * =A0Based on the original ndfc driver by Thomas Gleixner\n" "> + *\n" - "> + * \302\240Copyright 2006 IBM\n" + "> + * =A0Copyright 2006 IBM\n" "> + *\n" - "> + * \302\240This program is free software; you can redistribute\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240 it and/or\n" - "> modify it + * \302\240under \302\240the terms of\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240 the GNU General \302\240Public License\n" - "> as published by the + * \302\240Free Software Foundation; \302\240either version 2 of\n" - "> the\302\240License, or (at your + * \302\240option) any later version.\n" + "> + * =A0This program is free software; you can redistribute=A0=A0=A0=A0=A0=\n" + "=A0=A0=A0 it and/or\n" + "> modify it + * =A0under =A0the terms of=A0=A0=A0=A0=A0=A0=A0=A0 the GNU Ge=\n" + "neral =A0Public License\n" + "> as published by the + * =A0Free Software Foundation; =A0either version 2 =\n" + "of\n" + "> the=A0License, or (at your + * =A0option) any later version.\n" "> + *\n" "> + */\n" "> +#include <linux/module.h>\n" @@ -96,16 +113,20 @@ "> +\n" "> +\n" "> +struct of_ndfc {\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240__iomem void\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240*base;\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240struct resource\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240*res;\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240unsigned\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240bank_width;\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240unsigned \302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240chip_cnt;\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240unsigned char\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240chip_map[NDFC_MAX_BANKS];\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240struct nand_hw_control\302\240\302\240control;\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240struct nand_chip\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240chip;\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240struct mtd_info\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240mtd;\n" + "> +=A0=A0=A0=A0=A0=A0=A0__iomem void=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0*ba=\n" + "se;\n" + "> +=A0=A0=A0=A0=A0=A0=A0struct resource=A0=A0=A0=A0=A0=A0=A0=A0=A0*res;\n" + "> +=A0=A0=A0=A0=A0=A0=A0unsigned=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=\n" + "=A0=A0bank_width;\n" + "> +=A0=A0=A0=A0=A0=A0=A0unsigned =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=\n" + "=A0chip_cnt;\n" + "> +=A0=A0=A0=A0=A0=A0=A0unsigned char=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0chip_=\n" + "map[NDFC_MAX_BANKS];\n" + "> +=A0=A0=A0=A0=A0=A0=A0struct nand_hw_control=A0=A0control;\n" + "> +=A0=A0=A0=A0=A0=A0=A0struct nand_chip=A0=A0=A0=A0=A0=A0=A0=A0chip;\n" + "> +=A0=A0=A0=A0=A0=A0=A0struct mtd_info=A0=A0=A0=A0=A0=A0=A0=A0=A0mtd;\n" "> +#ifdef CONFIG_MTD_PARTITIONS\n" - "> +\302\240\302\240\302\240\302\240\302\240\302\240\302\240struct mtd_partition\302\240\302\240\302\240\302\240*parts;\n" + "> +=A0=A0=A0=A0=A0=A0=A0struct mtd_partition=A0=A0=A0=A0*parts;\n" "> +#endif\n" "> +};\n" "> +\n" @@ -114,7 +135,8 @@ "> +\treturn __raw_readl(ndfc->base + off);\n" "> +}\n" "> +\n" - "> +static inline void ndfc_raw_writel(struct of_ndfc *ndfc, u32 off, u32 val)\n" + "> +static inline void ndfc_raw_writel(struct of_ndfc *ndfc, u32 off, u32 va=\n" + "l)\n" "> +{\n" "> +\t__raw_writel(val, ndfc->base + off);\n" "> +}\n" @@ -126,25 +148,25 @@ "> +\n" "> +static void ndfc_select_chip(struct mtd_info *mtd, int chip)\n" "> +{\n" - "> +\tstruct nand_chip *this = mtd->priv;\n" - "> +\tstruct of_ndfc *ndfc = this->priv;\n" + "> +\tstruct nand_chip *this =3D mtd->priv;\n" + "> +\tstruct of_ndfc *ndfc =3D this->priv;\n" "> +\tuint32_t ccr;\n" "> +\n" - "> +\tccr = ndfc_raw_readl(ndfc, NDFC_CCR);\n" - "> +\tif ((chip >= 0) && (chip < ndfc->chip_cnt)) {\n" - "> +\t\tccr &= ~NDFC_CCR_BS_MASK;\n" - "> +\t\tccr |= NDFC_CCR_BS(ndfc->chip_map[chip]);\n" + "> +\tccr =3D ndfc_raw_readl(ndfc, NDFC_CCR);\n" + "> +\tif ((chip >=3D 0) && (chip < ndfc->chip_cnt)) {\n" + "> +\t\tccr &=3D ~NDFC_CCR_BS_MASK;\n" + "> +\t\tccr |=3D NDFC_CCR_BS(ndfc->chip_map[chip]);\n" "> +\t} else\n" - "> +\t\tccr |= NDFC_CCR_RESET_CE;\n" + "> +\t\tccr |=3D NDFC_CCR_RESET_CE;\n" "> +\tndfc_raw_writel(ndfc, NDFC_CCR, ccr);\n" "> +}\n" "> +\n" "> +static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int\n" "> ctrl) +{\n" - "> +\tstruct nand_chip *this = mtd->priv;\n" - "> +\tstruct of_ndfc *ndfc = this->priv;\n" + "> +\tstruct nand_chip *this =3D mtd->priv;\n" + "> +\tstruct of_ndfc *ndfc =3D this->priv;\n" "> +\n" - "> +\tif (cmd == NAND_CMD_NONE)\n" + "> +\tif (cmd =3D=3D NAND_CMD_NONE)\n" "> +\t\treturn;\n" "> +\n" "> +\tif (ctrl & NAND_CLE)\n" @@ -155,8 +177,8 @@ "> +\n" "> +static int ndfc_ready(struct mtd_info *mtd)\n" "> +{\n" - "> +\tstruct nand_chip *this = mtd->priv;\n" - "> +\tstruct of_ndfc *ndfc = this->priv;\n" + "> +\tstruct nand_chip *this =3D mtd->priv;\n" + "> +\tstruct of_ndfc *ndfc =3D this->priv;\n" "> +\n" "> +\treturn ndfc_raw_readl(ndfc, NDFC_STAT) & NDFC_STAT_IS_READY;\n" "> +}\n" @@ -164,15 +186,16 @@ "> +static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)\n" "> +{\n" "> +\tuint32_t ccr;\n" - "> +\tstruct nand_chip *this = mtd->priv;\n" - "> +\tstruct of_ndfc *ndfc = this->priv;\n" + "> +\tstruct nand_chip *this =3D mtd->priv;\n" + "> +\tstruct of_ndfc *ndfc =3D this->priv;\n" "> +\n" - "> +\tccr = ndfc_raw_readl(ndfc, NDFC_CCR);\n" - "> +\tccr |= NDFC_CCR_RESET_ECC;\n" + "> +\tccr =3D ndfc_raw_readl(ndfc, NDFC_CCR);\n" + "> +\tccr |=3D NDFC_CCR_RESET_ECC;\n" "> +\tndfc_raw_writel(ndfc, NDFC_CCR, ccr);\n" "> +\twmb();\n" "\n" - "I suspect that when we use the in_be32() and friends functions for IO access, \n" + "I suspect that when we use the in_be32() and friends functions for IO acces=\n" + "s,=20\n" "the memory-barriers can go away.\n" "\n" "> +}\n" @@ -182,18 +205,18 @@ "> +\t\t\t const u_char *dat, u_char *ecc_code)\n" "> +{\n" "> +\tuint32_t ecc;\n" - "> +\tstruct nand_chip *this = mtd->priv;\n" - "> +\tstruct of_ndfc *ndfc = this->priv;\n" - "> +\tuint8_t *p = (uint8_t *)&ecc;\n" + "> +\tstruct nand_chip *this =3D mtd->priv;\n" + "> +\tstruct of_ndfc *ndfc =3D this->priv;\n" + "> +\tuint8_t *p =3D (uint8_t *)&ecc;\n" "> +\n" "> +\twmb();\n" "\n" "Same here.\n" "\n" - "> +\tecc = ndfc_raw_readl(ndfc, NDFC_ECC);\n" - "> +\tecc_code[0] = p[1];\n" - "> +\tecc_code[1] = p[2];\n" - "> +\tecc_code[2] = p[3];\n" + "> +\tecc =3D ndfc_raw_readl(ndfc, NDFC_ECC);\n" + "> +\tecc_code[0] =3D p[1];\n" + "> +\tecc_code[1] =3D p[2];\n" + "> +\tecc_code[2] =3D p[3];\n" "> +\n" "> +\treturn 0;\n" "> +}\n" @@ -208,32 +231,32 @@ "> + */\n" "> +static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)\n" "> +{\n" - "> +\tstruct nand_chip *this = mtd->priv;\n" - "> +\tstruct of_ndfc *ndfc = this->priv;\n" - "> +\tuint32_t *p = (uint32_t *) buf;\n" + "> +\tstruct nand_chip *this =3D mtd->priv;\n" + "> +\tstruct of_ndfc *ndfc =3D this->priv;\n" + "> +\tuint32_t *p =3D (uint32_t *) buf;\n" "> +\n" - "> +\tfor(;len > 0; len -= 4)\n" - "> +\t\t*p++ = ndfc_raw_readl(ndfc, NDFC_DATA);\n" + "> +\tfor(;len > 0; len -=3D 4)\n" + "> +\t\t*p++ =3D ndfc_raw_readl(ndfc, NDFC_DATA);\n" "> +}\n" "> +\n" "> +static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int\n" "> len) +{\n" - "> +\tstruct nand_chip *this = mtd->priv;\n" - "> +\tstruct of_ndfc *ndfc = this->priv;\n" - "> +\tuint32_t *p = (uint32_t *) buf;\n" + "> +\tstruct nand_chip *this =3D mtd->priv;\n" + "> +\tstruct of_ndfc *ndfc =3D this->priv;\n" + "> +\tuint32_t *p =3D (uint32_t *) buf;\n" "> +\n" - "> +\tfor(;len > 0; len -= 4)\n" + "> +\tfor(;len > 0; len -=3D 4)\n" "> +\t\tndfc_raw_writel(ndfc, NDFC_DATA, *p++);\n" "> +}\n" "> +\n" "> +static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int\n" "> len) +{\n" - "> +\tstruct nand_chip *this = mtd->priv;\n" - "> +\tstruct of_ndfc *ndfc = this->priv;\n" - "> +\tuint32_t *p = (uint32_t *) buf;\n" + "> +\tstruct nand_chip *this =3D mtd->priv;\n" + "> +\tstruct of_ndfc *ndfc =3D this->priv;\n" + "> +\tuint32_t *p =3D (uint32_t *) buf;\n" "> +\n" - "> +\tfor(;len > 0; len -= 4)\n" - "> +\t\tif (*p++ != ndfc_raw_readl(ndfc, NDFC_DATA))\n" + "> +\tfor(;len > 0; len -=3D 4)\n" + "> +\t\tif (*p++ !=3D ndfc_raw_readl(ndfc, NDFC_DATA))\n" "> +\t\t\treturn -EFAULT;\n" "> +\treturn 0;\n" "> +}\n" @@ -243,27 +266,27 @@ "> +static void ndfc_chip_init(struct nand_chip *chip,\n" "> +\t\t\t\tstruct of_ndfc *ndfc)\n" "> +{\n" - "> +\tchip->IO_ADDR_R = ndfc->base + NDFC_DATA;\n" - "> +\tchip->IO_ADDR_W = ndfc->base + NDFC_DATA;\n" - "> +\tchip->cmd_ctrl = ndfc_hwcontrol;\n" - "> +\tchip->dev_ready = ndfc_ready;\n" - "> +\tchip->select_chip = ndfc_select_chip;\n" - "> +\tchip->chip_delay = 50;\n" - "> +\tchip->priv = ndfc;\n" - "> +\tif (ndfc->bank_width == 2)\n" - "> +\t\tchip->options |= NAND_BUSWIDTH_16;\n" - "> +\tchip->controller = &ndfc->control;\n" - "> +\tchip->read_buf = ndfc_read_buf;\n" - "> +\tchip->write_buf = ndfc_write_buf;\n" - "> +\tchip->verify_buf = ndfc_verify_buf;\n" - "> +\tchip->ecc.correct = nand_correct_data;\n" - "> +\tchip->ecc.hwctl = ndfc_enable_hwecc;\n" - "> +\tchip->ecc.calculate = ndfc_calculate_ecc;\n" - "> +\tchip->ecc.mode = NAND_ECC_HW;\n" - "> +\tchip->ecc.size = 256;\n" - "> +\tchip->ecc.bytes = 3;\n" - "> +\tndfc->mtd.priv = chip;\n" - "> +\tndfc->mtd.owner = THIS_MODULE;\n" + "> +\tchip->IO_ADDR_R =3D ndfc->base + NDFC_DATA;\n" + "> +\tchip->IO_ADDR_W =3D ndfc->base + NDFC_DATA;\n" + "> +\tchip->cmd_ctrl =3D ndfc_hwcontrol;\n" + "> +\tchip->dev_ready =3D ndfc_ready;\n" + "> +\tchip->select_chip =3D ndfc_select_chip;\n" + "> +\tchip->chip_delay =3D 50;\n" + "> +\tchip->priv =3D ndfc;\n" + "> +\tif (ndfc->bank_width =3D=3D 2)\n" + "> +\t\tchip->options |=3D NAND_BUSWIDTH_16;\n" + "> +\tchip->controller =3D &ndfc->control;\n" + "> +\tchip->read_buf =3D ndfc_read_buf;\n" + "> +\tchip->write_buf =3D ndfc_write_buf;\n" + "> +\tchip->verify_buf =3D ndfc_verify_buf;\n" + "> +\tchip->ecc.correct =3D nand_correct_data;\n" + "> +\tchip->ecc.hwctl =3D ndfc_enable_hwecc;\n" + "> +\tchip->ecc.calculate =3D ndfc_calculate_ecc;\n" + "> +\tchip->ecc.mode =3D NAND_ECC_HW;\n" + "> +\tchip->ecc.size =3D 256;\n" + "> +\tchip->ecc.bytes =3D 3;\n" + "> +\tndfc->mtd.priv =3D chip;\n" + "> +\tndfc->mtd.owner =3D THIS_MODULE;\n" "> +}\n" "> +\n" "> +\n" @@ -275,13 +298,13 @@ "> +{\n" "> +\tconst char *partname;\n" "> +\tstatic const char *part_probe_types[]\n" - "> +\t\t= { \"cmdlinepart\", \"RedBoot\", NULL };\n" - "> +\tstruct device_node *dp = dev->node, *pp;\n" + "> +\t\t=3D { \"cmdlinepart\", \"RedBoot\", NULL };\n" + "> +\tstruct device_node *dp =3D dev->node, *pp;\n" "> +\tint nr_parts, i;\n" "> +\n" "> +\t/* First look for RedBoot table or partitions on the command\n" "> +\t * line, these take precedence over device tree information */\n" - "> +\tnr_parts = parse_mtd_partitions(&ndfc->mtd, part_probe_types,\n" + "> +\tnr_parts =3D parse_mtd_partitions(&ndfc->mtd, part_probe_types,\n" "> +\t\t\t\t\t&ndfc->parts, 0);\n" "> +\tif (nr_parts > 0) {\n" "> +\t\tadd_mtd_partitions(&ndfc->mtd, ndfc->parts, nr_parts);\n" @@ -289,47 +312,48 @@ "> +\t}\n" "> +\n" "> +\t/* First count the subnodes */\n" - "> +\tnr_parts = 0;\n" - "> +\tfor (pp = dp->child; pp; pp = pp->sibling)\n" + "> +\tnr_parts =3D 0;\n" + "> +\tfor (pp =3D dp->child; pp; pp =3D pp->sibling)\n" "> +\t\tnr_parts++;\n" "> +\n" - "> +\tif (nr_parts == 0)\n" + "> +\tif (nr_parts =3D=3D 0)\n" "> +\t\treturn 0;\n" "> +\n" - "> +\tndfc->parts = kzalloc(nr_parts * sizeof(*ndfc->parts),\n" + "> +\tndfc->parts =3D kzalloc(nr_parts * sizeof(*ndfc->parts),\n" "> +\t\t\t GFP_KERNEL);\n" "> +\tif (!ndfc->parts)\n" "> +\t\treturn -ENOMEM;\n" "> +\n" - "> +\tfor (pp = dp->child, i = 0; pp; pp = pp->sibling, i++) {\n" + "> +\tfor (pp =3D dp->child, i =3D 0; pp; pp =3D pp->sibling, i++) {\n" "> +\t\tconst u32 *reg;\n" "> +\t\tint len;\n" "> +\n" - "> +\t\treg = of_get_property(pp, \"reg\", &len);\n" - "> +\t\tif (!reg || (len != 2*sizeof(u32))) {\n" + "> +\t\treg =3D of_get_property(pp, \"reg\", &len);\n" + "> +\t\tif (!reg || (len !=3D 2*sizeof(u32))) {\n" "> +\t\t\tdev_err(&dev->dev, \"Invalid 'reg' on %s\\n\",\n" "> +\t\t\t\tdp->full_name);\n" "> +\t\t\tkfree(ndfc->parts);\n" - "> +\t\t\tndfc->parts = NULL;\n" + "> +\t\t\tndfc->parts =3D NULL;\n" "> +\t\t\treturn -EINVAL;\n" "> +\t\t}\n" - "> +\t\tndfc->parts[i].offset = reg[0];\n" - "> +\t\tndfc->parts[i].size = reg[1];\n" + "> +\t\tndfc->parts[i].offset =3D reg[0];\n" + "> +\t\tndfc->parts[i].size =3D reg[1];\n" "> +\n" - "> +\t\tpartname = of_get_property(pp, \"label\", &len);\n" + "> +\t\tpartname =3D of_get_property(pp, \"label\", &len);\n" "> +\t\tif (!partname)\n" - "> +\t\t\tpartname = of_get_property(pp, \"name\", &len);\n" - "> +\t\tndfc->parts[i].name = (char *)partname;\n" + "> +\t\t\tpartname =3D of_get_property(pp, \"name\", &len);\n" + "> +\t\tndfc->parts[i].name =3D (char *)partname;\n" "> +\n" "> +\t\tif (of_get_property(pp, \"read-only\", &len))\n" - "> +\t\t\tndfc->parts[i].mask_flags = MTD_WRITEABLE;\n" + "> +\t\t\tndfc->parts[i].mask_flags =3D MTD_WRITEABLE;\n" "> +\t}\n" "> +\n" "> +\treturn nr_parts;\n" "> +}\n" "\n" - "This parse_partition code looks very much like the code in the physmap_of \n" - "driver. I think it would be a good idea not to duplicate this code, but to \n" + "This parse_partition code looks very much like the code in the physmap_of=20\n" + "driver. I think it would be a good idea not to duplicate this code, but to=\n" + "=20\n" "extract it and use one version in both drivers.\n" "\n" "> +#else /* MTD_PARTITIONS */\n" @@ -342,7 +366,7 @@ "> +{\n" "> +\tstruct of_ndfc *ndfc;\n" "> +\n" - "> +\tndfc = dev_get_drvdata(&dev->dev);\n" + "> +\tndfc =3D dev_get_drvdata(&dev->dev);\n" "> +\tif (!ndfc)\n" "> +\t\treturn 0;\n" "> +\n" @@ -370,7 +394,8 @@ "> +}\n" "> +\n" "> +\n" - "> +static int __devinit ndfc_map_banks(struct of_ndfc *ndfc, const u32 *mask)\n" + "> +static int __devinit ndfc_map_banks(struct of_ndfc *ndfc, const u32 *mas=\n" + "k)\n" "> +{\n" "> +\tunsigned cnt, i, tmp;\n" "> +\tuint32_t bcr;\n" @@ -379,25 +404,25 @@ "> +\t\treturn -EINVAL;\n" "> +\n" "> +\t/* Disable all banks */\n" - "> +\tfor (cnt = 0; cnt < NDFC_MAX_BANKS; cnt++) {\n" + "> +\tfor (cnt =3D 0; cnt < NDFC_MAX_BANKS; cnt++) {\n" "> +\t\tndfc_raw_writel(ndfc, NDFC_BCFG0 + (cnt << 2), 0);\n" "> +\t}\n" "> +\n" "> +\t/* Enable bank and set default RE/WE/CE timings */\n" - "> +\tbcr = NDFC_BxCFG_EN | NDFC_BxCFG_RR(2) | NDFC_BxCFG_RWH(2) |\n" + "> +\tbcr =3D NDFC_BxCFG_EN | NDFC_BxCFG_RR(2) | NDFC_BxCFG_RWH(2) |\n" "> +\t\t\t\tNDFC_BxCFG_RWP(2) | NDFC_BxCFG_CRW(2);\n" - "> +\tif (ndfc->bank_width == 2)\n" - "> +\t\tbcr |= NDFC_BxCFG_SZ_16BIT;\n" + "> +\tif (ndfc->bank_width =3D=3D 2)\n" + "> +\t\tbcr |=3D NDFC_BxCFG_SZ_16BIT;\n" "> +\n" - "> +\tcnt = 0;\n" - "> +\ttmp = *mask;\n" - "> +\twhile ((i = ffs(tmp)) && (cnt < NDFC_MAX_BANKS)) {\n" + "> +\tcnt =3D 0;\n" + "> +\ttmp =3D *mask;\n" + "> +\twhile ((i =3D ffs(tmp)) && (cnt < NDFC_MAX_BANKS)) {\n" "> +\t\ti--;\n" - "> +\t\ttmp &= ~(1 << i);\n" - "> +\t\tndfc->chip_map[cnt++] = i;\n" + "> +\t\ttmp &=3D ~(1 << i);\n" + "> +\t\tndfc->chip_map[cnt++] =3D i;\n" "> +\t\tndfc_raw_writel(ndfc, NDFC_BCFG0 + (i << 2), bcr);\n" "> +\t}\n" - "> +\tndfc->chip_cnt = cnt;\n" + "> +\tndfc->chip_cnt =3D cnt;\n" "> +\treturn cnt;\n" "> +}\n" "> +\n" @@ -405,14 +430,14 @@ "> +static int __devinit of_ndfc_probe(struct of_device *dev,\n" "> +\t\t\t\t const struct of_device_id *match)\n" "> +{\n" - "> +\tstruct device_node *dp = dev->node;\n" + "> +\tstruct device_node *dp =3D dev->node;\n" "> +\tstruct resource res;\n" "> +\tstruct of_ndfc *ndfc;\n" "> +\tconst u32 *prop;\n" "> +\tresource_size_t rlen;\n" "> +\tint err;\n" "> +\n" - "> +\terr = -ENXIO;\n" + "> +\terr =3D -ENXIO;\n" "> +\tif (of_address_to_resource(dp, 0, &res)) {\n" "> +\t\tdev_err(&dev->dev, \"can't get IO address from device tree\\n\");\n" "> +\t\tgoto err_out;\n" @@ -421,36 +446,36 @@ "> + \tdev_dbg(&dev->dev, \"regs: %.8llx-%.8llx\\n\",\n" "> +\t\t(unsigned long long)res.start, (unsigned long long)res.end);\n" "> +\n" - "> +\tndfc = kzalloc(sizeof(struct of_ndfc), GFP_KERNEL);\n" + "> +\tndfc =3D kzalloc(sizeof(struct of_ndfc), GFP_KERNEL);\n" "> +\tif (!ndfc) {\n" - "> +\t\terr = -ENOMEM;\n" + "> +\t\terr =3D -ENOMEM;\n" "> +\t\tgoto err_out;\n" "> +\t}\n" "> +\n" - "> +\trlen = res.end - res.start + 1;\n" - "> +\tndfc->res = request_mem_region(res.start, rlen, dev->dev.bus_id);\n" + "> +\trlen =3D res.end - res.start + 1;\n" + "> +\tndfc->res =3D request_mem_region(res.start, rlen, dev->dev.bus_id);\n" "> +\tif (!ndfc->res) {\n" - "> +\t\terr = -EBUSY;\n" + "> +\t\terr =3D -EBUSY;\n" "> +\t\tgoto err_free_out;\n" "> +\t}\n" "> +\n" - "> +\tndfc->base = ioremap(res.start, rlen);\n" + "> +\tndfc->base =3D ioremap(res.start, rlen);\n" "> +\tif (!ndfc->base) {\n" - "> +\t\terr = -ENXIO;\n" + "> +\t\terr =3D -ENXIO;\n" "> +\t\tgoto err_rel_out;\n" "> +\t}\n" "> +\n" "> +\tspin_lock_init(&ndfc->control.lock);\n" "> +\tinit_waitqueue_head(&ndfc->control.wq);\n" "> +\n" - "> +\tprop = of_get_property(dp, \"bank-width\", NULL);\n" - "> +\tndfc->bank_width = ((prop) && (*prop) == 2) ? 2 : 1;\n" + "> +\tprop =3D of_get_property(dp, \"bank-width\", NULL);\n" + "> +\tndfc->bank_width =3D ((prop) && (*prop) =3D=3D 2) ? 2 : 1;\n" "> +\n" - "> +\tprop = of_get_property(dp, \"bank-mask\", NULL);\n" - "> +\terr = ndfc_map_banks(ndfc, prop);\n" - "> +\tif (err <= 0) {\n" + "> +\tprop =3D of_get_property(dp, \"bank-mask\", NULL);\n" + "> +\terr =3D ndfc_map_banks(ndfc, prop);\n" + "> +\tif (err <=3D 0) {\n" "> +\t\tdev_err(&dev->dev, \"no banks found\\n\");\n" - "> +\t\terr = -ENODEV;\n" + "> +\t\terr =3D -ENODEV;\n" "> +\t\tgoto err_unmap_out;\n" "> +\t}\n" "> +\n" @@ -460,21 +485,21 @@ "> +\tdev_info(&dev->dev, \"NDFC driver initialized. Chip-Rev: 0x%08x\\n\",\n" "> +\t\t\tndfc_raw_readl(ndfc, NDFC_REVID));\n" "> +\n" - "> +\terr = nand_scan_ident(&ndfc->mtd, ndfc->chip_cnt);\n" + "> +\terr =3D nand_scan_ident(&ndfc->mtd, ndfc->chip_cnt);\n" "> +\tif (err)\n" "> +\t\tgoto err_dat_out;\n" "> +\n" - "> +\tif ((ndfc->mtd.writesize != 2048) && (ndfc->mtd.writesize != 512)) {\n" + "> +\tif ((ndfc->mtd.writesize !=3D 2048) && (ndfc->mtd.writesize !=3D 512)) {\n" "> +\t\tdev_err(&dev->dev, \"unexpected NAND flash writesize %d\",\n" "> +\t\t\tndfc->mtd.writesize);\n" "> +\t\tgoto err_dat_out;\n" "> +\t}\n" "> +\n" - "> +\terr = nand_scan_tail(&ndfc->mtd);\n" + "> +\terr =3D nand_scan_tail(&ndfc->mtd);\n" "> +\tif (err)\n" "> +\t\tgoto err_dat_out;\n" "> +\n" - "> +\terr = parse_partitions(ndfc, dev);\n" + "> +\terr =3D parse_partitions(ndfc, dev);\n" "> +\tif (err < 0)\n" "> +\t\tgoto err_dat_out;\n" "> +\n" @@ -498,19 +523,19 @@ "> +\treturn err;\n" "> +}\n" "> +\n" - "> +static struct of_device_id of_ndfc_match[] = {\n" + "> +static struct of_device_id of_ndfc_match[] =3D {\n" "> +\t{\n" - "> +\t\t.compatible\t= \"ibm,ndfc\",\n" + "> +\t\t.compatible\t=3D \"ibm,ndfc\",\n" "> +\t},\n" "> +\t{ },\n" "> +};\n" "> +MODULE_DEVICE_TABLE(of, of_ndfc_match);\n" "> +\n" - "> +static struct of_platform_driver of_ndfc_driver = {\n" - "> +\t.name\t\t= \"of-ndfc\",\n" - "> +\t.match_table\t= of_ndfc_match,\n" - "> +\t.probe\t\t= of_ndfc_probe,\n" - "> +\t.remove\t\t= of_ndfc_remove,\n" + "> +static struct of_platform_driver of_ndfc_driver =3D {\n" + "> +\t.name\t\t=3D \"of-ndfc\",\n" + "> +\t.match_table\t=3D of_ndfc_match,\n" + "> +\t.probe\t\t=3D of_ndfc_probe,\n" + "> +\t.remove\t\t=3D of_ndfc_remove,\n" "> +};\n" "> +\n" "> +static int __init of_ndfc_init(void)\n" @@ -532,7 +557,8 @@ "> +MODULE_DESCRIPTION(\"OF driver for NDFC\");\n" "> diff -pruN linux-2.6.orig/include/linux/mtd/ndfc.h\n" "> linux-2.6/include/linux/mtd/ndfc.h ---\n" - "> linux-2.6.orig/include/linux/mtd/ndfc.h\t2007-10-25 19:20:42.000000000 +0400\n" + "> linux-2.6.orig/include/linux/mtd/ndfc.h\t2007-10-25 19:20:42.000000000 +04=\n" + "00\n" "> +++ linux-2.6/include/linux/mtd/ndfc.h\t2007-10-26 16:19:42.000000000 +0400\n" "> @@ -52,6 +52,10 @@\n" "> #define NDFC_BxCFG_SZ_MASK\t0x08000000 /* Bank Size */\n" @@ -548,4 +574,4 @@ "Best regards,\n" Stefan -ac11e9d116e202ee83f856b218036beced9d93d372aeebec485474354b40510b +f00fb0ad311fdf1eadd37bb20c3858529ba33ae77c0b8bc6cf5d4a1e8c95d271
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.