Re: [PATCH 1/2] port ndfc driver to of platform
On Friday 15 August 2008, Sean MacLennan wrote: Port the ndfc driver to an OF platform driver. Signed-off-by: Sean MacLennan [EMAIL PROTECTED] Acked-by: Arnd Bergmann [EMAIL PROTECTED] Looks great, but I just noticed one more detail: +static const struct of_device_id ndfc_match[] = { + { .compatible = amcc,ndfc, }, + {} }; You should add MODULE_DEVICE_TABLE(of, ndfc_match); to enable module auto-loading. Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 1/2] port ndfc driver to of platform
Added in the MODULE_DEVICE_TABLE. Cheers, Sean Port of the ndfc driver to an of platform driver. Signed-off-by: Sean MacLennan [EMAIL PROTECTED] Acked-by: Arnd Bergmann [EMAIL PROTECTED] --- diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 41f361c..ab0d77e 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -165,7 +165,7 @@ config MTD_NAND_S3C2410_HWECC config MTD_NAND_NDFC tristate NDFC NanD Flash Controller - depends on 4xx !PPC_MERGE + depends on 4xx select MTD_NAND_ECC_SMC help NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 955959e..abdb42f 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -5,9 +5,13 @@ * Platform independend driver for NDFC (NanD Flash Controller) * integrated into EP440 cores * + * Ported to an OF platform driver by Sean MacLennan + * * Author: Thomas Gleixner * * Copyright 2006 IBM + * Copyright 2008 PIKA Technologies + *Sean MacLennan [EMAIL PROTECTED] * * 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 @@ -21,27 +25,17 @@ #include linux/mtd/partitions.h #include linux/mtd/ndfc.h #include linux/mtd/mtd.h -#include linux/platform_device.h - +#include linux/of_platform.h #include asm/io.h -#ifdef CONFIG_40x -#include asm/ibm405.h -#else -#include asm/ibm44x.h -#endif - -struct ndfc_nand_mtd { - struct mtd_info mtd; - struct nand_chipchip; - struct platform_nand_chip *pl_chip; -}; -static struct ndfc_nand_mtd ndfc_mtd[NDFC_MAX_BANKS]; struct ndfc_controller { - void __iomem*ndfcbase; - struct nand_hw_control ndfc_control; - atomic_tchilds_active; + struct of_device *ofdev; + void __iomem *ndfcbase; + struct mtd_info mtd; + struct nand_chip chip; + int chip_select; + struct nand_hw_control ndfc_control; }; static struct ndfc_controller ndfc_ctrl; @@ -50,17 +44,14 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) { uint32_t ccr; struct ndfc_controller *ndfc = ndfc_ctrl; - struct nand_chip *nandchip = mtd-priv; - struct ndfc_nand_mtd *nandmtd = nandchip-priv; - struct platform_nand_chip *pchip = nandmtd-pl_chip; - ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); + ccr = in_be32(ndfc-ndfcbase + NDFC_CCR); if (chip = 0) { ccr = ~NDFC_CCR_BS_MASK; - ccr |= NDFC_CCR_BS(chip + pchip-chip_offset); + ccr |= NDFC_CCR_BS(chip + ndfc-chip_select); } else ccr |= NDFC_CCR_RESET_CE; - __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); + out_be32(ndfc-ndfcbase + NDFC_CCR, ccr); } static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) @@ -80,7 +71,7 @@ static int ndfc_ready(struct mtd_info *mtd) { struct ndfc_controller *ndfc = ndfc_ctrl; - return __raw_readl(ndfc-ndfcbase + NDFC_STAT) NDFC_STAT_IS_READY; + return in_be32(ndfc-ndfcbase + NDFC_STAT) NDFC_STAT_IS_READY; } static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) @@ -88,9 +79,9 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) uint32_t ccr; struct ndfc_controller *ndfc = ndfc_ctrl; - ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); + ccr = in_be32(ndfc-ndfcbase + NDFC_CCR); ccr |= NDFC_CCR_RESET_ECC; - __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); + out_be32(ndfc-ndfcbase + NDFC_CCR, ccr); wmb(); } @@ -102,9 +93,10 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, uint8_t *p = (uint8_t *)ecc; wmb(); - ecc = __raw_readl(ndfc-ndfcbase + NDFC_ECC); - ecc_code[0] = p[1]; - ecc_code[1] = p[2]; + ecc = in_be32(ndfc-ndfcbase + NDFC_ECC); + /* The NDFC uses Smart Media (SMC) bytes order */ + ecc_code[0] = p[2]; + ecc_code[1] = p[1]; ecc_code[2] = p[3]; return 0; @@ -123,7 +115,7 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) - *p++ = __raw_readl(ndfc-ndfcbase + NDFC_DATA); + *p++ = in_be32(ndfc-ndfcbase + NDFC_DATA); } static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) @@ -132,7 +124,7 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) - __raw_writel(*p++, ndfc-ndfcbase + NDFC_DATA); + out_be32(ndfc-ndfcbase + NDFC_DATA, *p++); } static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) @@
Re: [PATCH 1/2] port ndfc driver to of platform
On Wednesday 13 August 2008, Sean MacLennan wrote: Port of the ndfc driver to an of platform driver. Look good overall, thanks for following up on this. +struct ndfc_ctrl { + struct device *dev; + void __iomem *ndfcbase; + struct mtd_info mtd; + struct nand_chip chip; + int chip_select; + struct nand_hw_control ndfc_control; }; conceptually, I would lint to the ofdev, not the dev, even if you don't need the extra information. static void ndfc_select_chip(struct mtd_info *mtd, int chip) { uint32_t ccr; - struct ndfc_controller *ndfc = ndfc_ctrl; - struct nand_chip *nandchip = mtd-priv; - struct ndfc_nand_mtd *nandmtd = nandchip-priv; - struct platform_nand_chip *pchip = nandmtd-pl_chip; + struct ndfc_ctrl *ndfc = ndfc_ctrl; ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); This already exists, but I noticed it now: device drivers should not user __raw_readl/__raw_writel for accessing ioremapped storage. Instead, you should use ioread32_be or in_be32. @@ -83,7 +79,7 @@ static int ndfc_ready(struct mtd_info *mtd) static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) { uint32_t ccr; - struct ndfc_controller *ndfc = ndfc_ctrl; + struct ndfc_ctrl *ndfc = ndfc_ctrl; ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); ccr |= NDFC_CCR_RESET_ECC; You have lots of these changes, which do not appear necessary -- if you just keep the struct ndfc_controller name, your patch will be a lot smaller. -static int ndfc_nand_probe(struct platform_device *pdev) -{ - struct platform_nand_ctrl *nc = pdev-dev.platform_data; - struct ndfc_controller_settings *settings = nc-priv; - struct resource *res = pdev-resource; - struct ndfc_controller *ndfc = ndfc_ctrl; - unsigned long long phys = settings-ndfc_erpn | res-start; + spin_lock_init(ndfc-ndfc_control.lock); + init_waitqueue_head(ndfc-ndfc_control.wq); + ndfc-dev = ofdev-dev; + dev_set_drvdata(ofdev-dev, ndfc); + + /* Read the reg property to get the chip select */ + reg = of_get_property(ofdev-node, reg, len); + if (reg == NULL || len != 12) { + dev_err(ofdev-dev, unable read reg property (%d)\n, len); + return -ENOENT; + } + ndfc-chip_select = *reg; - ndfc-ndfcbase = ioremap((phys_addr_t)phys, res-end - res-start + 1); + ndfc-ndfcbase = ioremap(reg[1], reg[2]); This could be better expressed as of_iomap(). - platform_set_drvdata(pdev, ndfc); + __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); - printk(NDFC NAND Driver initialized. Chip-Rev: 0x%08x\n, -__raw_readl(ndfc-ndfcbase + NDFC_REVID)); + /* Set the bank settings */ + reg = of_get_property(ofdev-node, bank_settings, NULL); + bank_settings = reg ? *reg : 0x8000; Your device tree does have a bank_setting, so why not assume that all others will have it as well? I would remove the default. Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 1/2] port ndfc driver to of platform
On Thu, 14 Aug 2008 11:53:07 +0200 Arnd Bergmann [EMAIL PROTECTED] wrote: + ndfc-ndfcbase = ioremap(reg[1], reg[2]); This could be better expressed as of_iomap(). I tried of_iomap(), but it doesn't seem to like the 3 value reg. i.e. It doesn't skip the chip select. And since I need to read the reg property to get the chip select any way, I just used the value directly. - platform_set_drvdata(pdev, ndfc); + __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); - printk(NDFC NAND Driver initialized. Chip-Rev: 0x%08x\n, - __raw_readl(ndfc-ndfcbase + NDFC_REVID)); + /* Set the bank settings */ + reg = of_get_property(ofdev-node, bank_settings, NULL); + bank_settings = reg ? *reg : 0x8000; Your device tree does have a bank_setting, so why not assume that all others will have it as well? I would remove the default. I am thinking of making the bank settings an optional value. I assume most people with 44x chips with NAND will be using u-boot. If you enable NAND in u-boot, it should configure the bank settings for you. I put the bank setting in my dts just to show a complete configuration. Cheers, Sean ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 1/2] port ndfc driver to of platform
Second version of patch with cleanups. Note that this patch is slightly different I diffed the last patch against my master git rather than Linus' master git :( The difference is that my git already had the ports to arch/powerpc. Cheers, Sean Port of the ndfc driver to an of platform driver. Signed-off-by: Sean MacLennan [EMAIL PROTECTED] --- diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 955959e..f09cd27 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -5,9 +5,13 @@ * Platform independend driver for NDFC (NanD Flash Controller) * integrated into EP440 cores * + * Ported to an OF platform driver by Sean MacLennan + * * Author: Thomas Gleixner * * Copyright 2006 IBM + * Copyright 2008 PIKA Technologies + *Sean MacLennan [EMAIL PROTECTED] * * 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 @@ -21,27 +25,17 @@ #include linux/mtd/partitions.h #include linux/mtd/ndfc.h #include linux/mtd/mtd.h -#include linux/platform_device.h - +#include linux/of_platform.h #include asm/io.h -#ifdef CONFIG_40x -#include asm/ibm405.h -#else -#include asm/ibm44x.h -#endif - -struct ndfc_nand_mtd { - struct mtd_info mtd; - struct nand_chipchip; - struct platform_nand_chip *pl_chip; -}; -static struct ndfc_nand_mtd ndfc_mtd[NDFC_MAX_BANKS]; struct ndfc_controller { - void __iomem*ndfcbase; - struct nand_hw_control ndfc_control; - atomic_tchilds_active; + struct of_device *ofdev; + void __iomem *ndfcbase; + struct mtd_info mtd; + struct nand_chip chip; + int chip_select; + struct nand_hw_control ndfc_control; }; static struct ndfc_controller ndfc_ctrl; @@ -50,17 +44,14 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) { uint32_t ccr; struct ndfc_controller *ndfc = ndfc_ctrl; - struct nand_chip *nandchip = mtd-priv; - struct ndfc_nand_mtd *nandmtd = nandchip-priv; - struct platform_nand_chip *pchip = nandmtd-pl_chip; - ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); + ccr = in_be32(ndfc-ndfcbase + NDFC_CCR); if (chip = 0) { ccr = ~NDFC_CCR_BS_MASK; - ccr |= NDFC_CCR_BS(chip + pchip-chip_offset); + ccr |= NDFC_CCR_BS(chip + ndfc-chip_select); } else ccr |= NDFC_CCR_RESET_CE; - __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); + out_be32(ndfc-ndfcbase + NDFC_CCR, ccr); } static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) @@ -80,7 +71,7 @@ static int ndfc_ready(struct mtd_info *mtd) { struct ndfc_controller *ndfc = ndfc_ctrl; - return __raw_readl(ndfc-ndfcbase + NDFC_STAT) NDFC_STAT_IS_READY; + return in_be32(ndfc-ndfcbase + NDFC_STAT) NDFC_STAT_IS_READY; } static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) @@ -88,9 +79,9 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) uint32_t ccr; struct ndfc_controller *ndfc = ndfc_ctrl; - ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); + ccr = in_be32(ndfc-ndfcbase + NDFC_CCR); ccr |= NDFC_CCR_RESET_ECC; - __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); + out_be32(ndfc-ndfcbase + NDFC_CCR, ccr); wmb(); } @@ -102,9 +93,10 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, uint8_t *p = (uint8_t *)ecc; wmb(); - ecc = __raw_readl(ndfc-ndfcbase + NDFC_ECC); - ecc_code[0] = p[1]; - ecc_code[1] = p[2]; + ecc = in_be32(ndfc-ndfcbase + NDFC_ECC); + /* The NDFC uses Smart Media (SMC) bytes order */ + ecc_code[0] = p[2]; + ecc_code[1] = p[1]; ecc_code[2] = p[3]; return 0; @@ -123,7 +115,7 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) - *p++ = __raw_readl(ndfc-ndfcbase + NDFC_DATA); + *p++ = in_be32(ndfc-ndfcbase + NDFC_DATA); } static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) @@ -132,7 +124,7 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) - __raw_writel(*p++, ndfc-ndfcbase + NDFC_DATA); + out_be32(ndfc-ndfcbase + NDFC_DATA, *p++); } static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) @@ -141,7 +133,7 @@ static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) - if (*p++ != __raw_readl(ndfc-ndfcbase + NDFC_DATA)) + if (*p++ != in_be32(ndfc-ndfcbase +
Re: [PATCH 1/2] port ndfc driver to of platform
On Thu, 14 Aug 2008 22:16:45 +0200 Arnd Bergmann [EMAIL PROTECTED] wrote: If of_iomap and of_address_to_resource don't work properly, there is probably something wrong in your device tree, maybe an incorrect #size-cells or #address-cells or ranges property in one of the parents. You need to fix this anyway. Ga, no my dts is wrong. I must have looked at it a dozen times before I clued in that now that ndfc is a proper of driver I need to specify the chip select and the *offset*, not the chip select and the *address*. New patches soon. Cheers, Sean ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 1/2] port ndfc driver to of platform
Port the ndfc driver to an OF platform driver. Signed-off-by: Sean MacLennan [EMAIL PROTECTED] --- diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 41f361c..ab0d77e 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -165,7 +165,7 @@ config MTD_NAND_S3C2410_HWECC config MTD_NAND_NDFC tristate NDFC NanD Flash Controller - depends on 4xx !PPC_MERGE + depends on 4xx select MTD_NAND_ECC_SMC help NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 955959e..75a3bf0 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -5,9 +5,13 @@ * Platform independend driver for NDFC (NanD Flash Controller) * integrated into EP440 cores * + * Ported to an OF platform driver by Sean MacLennan + * * Author: Thomas Gleixner * * Copyright 2006 IBM + * Copyright 2008 PIKA Technologies + *Sean MacLennan [EMAIL PROTECTED] * * 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 @@ -21,27 +25,17 @@ #include linux/mtd/partitions.h #include linux/mtd/ndfc.h #include linux/mtd/mtd.h -#include linux/platform_device.h - +#include linux/of_platform.h #include asm/io.h -#ifdef CONFIG_40x -#include asm/ibm405.h -#else -#include asm/ibm44x.h -#endif - -struct ndfc_nand_mtd { - struct mtd_info mtd; - struct nand_chipchip; - struct platform_nand_chip *pl_chip; -}; -static struct ndfc_nand_mtd ndfc_mtd[NDFC_MAX_BANKS]; struct ndfc_controller { - void __iomem*ndfcbase; - struct nand_hw_control ndfc_control; - atomic_tchilds_active; + struct of_device *ofdev; + void __iomem *ndfcbase; + struct mtd_info mtd; + struct nand_chip chip; + int chip_select; + struct nand_hw_control ndfc_control; }; static struct ndfc_controller ndfc_ctrl; @@ -50,17 +44,14 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) { uint32_t ccr; struct ndfc_controller *ndfc = ndfc_ctrl; - struct nand_chip *nandchip = mtd-priv; - struct ndfc_nand_mtd *nandmtd = nandchip-priv; - struct platform_nand_chip *pchip = nandmtd-pl_chip; - ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); + ccr = in_be32(ndfc-ndfcbase + NDFC_CCR); if (chip = 0) { ccr = ~NDFC_CCR_BS_MASK; - ccr |= NDFC_CCR_BS(chip + pchip-chip_offset); + ccr |= NDFC_CCR_BS(chip + ndfc-chip_select); } else ccr |= NDFC_CCR_RESET_CE; - __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); + out_be32(ndfc-ndfcbase + NDFC_CCR, ccr); } static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) @@ -80,7 +71,7 @@ static int ndfc_ready(struct mtd_info *mtd) { struct ndfc_controller *ndfc = ndfc_ctrl; - return __raw_readl(ndfc-ndfcbase + NDFC_STAT) NDFC_STAT_IS_READY; + return in_be32(ndfc-ndfcbase + NDFC_STAT) NDFC_STAT_IS_READY; } static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) @@ -88,9 +79,9 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) uint32_t ccr; struct ndfc_controller *ndfc = ndfc_ctrl; - ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); + ccr = in_be32(ndfc-ndfcbase + NDFC_CCR); ccr |= NDFC_CCR_RESET_ECC; - __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); + out_be32(ndfc-ndfcbase + NDFC_CCR, ccr); wmb(); } @@ -102,9 +93,10 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, uint8_t *p = (uint8_t *)ecc; wmb(); - ecc = __raw_readl(ndfc-ndfcbase + NDFC_ECC); - ecc_code[0] = p[1]; - ecc_code[1] = p[2]; + ecc = in_be32(ndfc-ndfcbase + NDFC_ECC); + /* The NDFC uses Smart Media (SMC) bytes order */ + ecc_code[0] = p[2]; + ecc_code[1] = p[1]; ecc_code[2] = p[3]; return 0; @@ -123,7 +115,7 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) - *p++ = __raw_readl(ndfc-ndfcbase + NDFC_DATA); + *p++ = in_be32(ndfc-ndfcbase + NDFC_DATA); } static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) @@ -132,7 +124,7 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) - __raw_writel(*p++, ndfc-ndfcbase + NDFC_DATA); + out_be32(ndfc-ndfcbase + NDFC_DATA, *p++); } static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) @@ -141,7 +133,7 @@ static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
Re: [PATCH 1/2] port ndfc driver to of platform
Port of the ndfc driver to an of platform driver. Signed-off-by: Sean MacLennan [EMAIL PROTECTED] --- diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index efb1ab6..55aec25 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -5,9 +5,13 @@ * Platform independend driver for NDFC (NanD Flash Controller) * integrated into EP440 cores * + * Ported to an OF platform driver by Sean MacLennan + * * Author: Thomas Gleixner * * Copyright 2006 IBM + * Copyright 2008 PIKA Technologies + *Sean MacLennan [EMAIL PROTECTED] * * 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 @@ -23,38 +27,30 @@ #include linux/mtd/mtd.h #include linux/proc_fs.h #include linux/seq_file.h -#include linux/platform_device.h - +#include linux/of_platform.h #include asm/io.h -struct ndfc_nand_mtd { - struct mtd_info mtd; - struct nand_chipchip; - struct platform_nand_chip *pl_chip; -}; - -static struct ndfc_nand_mtd ndfc_mtd[NDFC_MAX_BANKS]; -struct ndfc_controller { - void __iomem*ndfcbase; - struct nand_hw_control ndfc_control; - atomic_tchilds_active; +struct ndfc_ctrl { + struct device *dev; + void __iomem *ndfcbase; + struct mtd_info mtd; + struct nand_chip chip; + int chip_select; + struct nand_hw_control ndfc_control; }; -static struct ndfc_controller ndfc_ctrl; +static struct ndfc_ctrl ndfc_ctrl; static void ndfc_select_chip(struct mtd_info *mtd, int chip) { uint32_t ccr; - struct ndfc_controller *ndfc = ndfc_ctrl; - struct nand_chip *nandchip = mtd-priv; - struct ndfc_nand_mtd *nandmtd = nandchip-priv; - struct platform_nand_chip *pchip = nandmtd-pl_chip; + struct ndfc_ctrl *ndfc = ndfc_ctrl; ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); if (chip = 0) { ccr = ~NDFC_CCR_BS_MASK; - ccr |= NDFC_CCR_BS(chip + pchip-chip_offset); + ccr |= NDFC_CCR_BS(chip + ndfc-chip_select); } else ccr |= NDFC_CCR_RESET_CE; __raw_writel(ccr, ndfc-ndfcbase + NDFC_CCR); @@ -62,7 +58,7 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct ndfc_controller *ndfc = ndfc_ctrl; + struct ndfc_ctrl *ndfc = ndfc_ctrl; if (cmd == NAND_CMD_NONE) return; @@ -75,7 +71,7 @@ static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) static int ndfc_ready(struct mtd_info *mtd) { - struct ndfc_controller *ndfc = ndfc_ctrl; + struct ndfc_ctrl *ndfc = ndfc_ctrl; return __raw_readl(ndfc-ndfcbase + NDFC_STAT) NDFC_STAT_IS_READY; } @@ -83,7 +79,7 @@ static int ndfc_ready(struct mtd_info *mtd) static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) { uint32_t ccr; - struct ndfc_controller *ndfc = ndfc_ctrl; + struct ndfc_ctrl *ndfc = ndfc_ctrl; ccr = __raw_readl(ndfc-ndfcbase + NDFC_CCR); ccr |= NDFC_CCR_RESET_ECC; @@ -94,7 +90,7 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) static int ndfc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { - struct ndfc_controller *ndfc = ndfc_ctrl; + struct ndfc_ctrl *ndfc = ndfc_ctrl; uint32_t ecc; uint8_t *p = (uint8_t *)ecc; @@ -117,7 +113,7 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, */ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { - struct ndfc_controller *ndfc = ndfc_ctrl; + struct ndfc_ctrl *ndfc = ndfc_ctrl; uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) @@ -126,7 +122,7 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct ndfc_controller *ndfc = ndfc_ctrl; + struct ndfc_ctrl *ndfc = ndfc_ctrl; uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) @@ -135,7 +131,7 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { - struct ndfc_controller *ndfc = ndfc_ctrl; + struct ndfc_ctrl *ndfc = ndfc_ctrl; uint32_t *p = (uint32_t *) buf; for(;len 0; len -= 4) @@ -147,10 +143,18 @@ static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) /* * Initialize chip structure */ -static void ndfc_chip_init(struct ndfc_nand_mtd *mtd) +static int ndfc_chip_init(struct ndfc_ctrl *ndfc, struct device_node *node) { - struct ndfc_controller *ndfc = ndfc_ctrl; - struct