X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Far71xx%2Ffiles%2Fdrivers%2Fmtd%2Fnand%2Frb750_nand.c;h=0604c5a235952f0419d45400c057204f4af8540c;hb=9db9072d6767e5910e01b8962171c89359ab7a14;hp=b6adb41d995a297fa8efbe6fed3af41973851da5;hpb=aa0c8c4885dc6a5bc4650c55673000d862bf2612;p=openwrt%2Fstaging%2Fchunkeey.git diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c b/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c index b6adb41d99..0604c5a235 100644 --- a/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c +++ b/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c @@ -1,14 +1,15 @@ /* * NAND flash driver for the MikroTik RouterBOARD 750 * - * Copyright (C) 2010 Gabor Juhos + * Copyright (C) 2010-2012 Gabor Juhos * * 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 +#include +#include #include #include #include @@ -16,8 +17,9 @@ #include #include -#include -#include +#include +#include +#include #define DRV_NAME "rb750-nand" #define DRV_VERSION "0.1.0" @@ -29,20 +31,24 @@ #define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE) #define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE) #define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY) -#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE) #define RB750_NAND_DATA_SHIFT 1 #define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT) #define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY) #define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \ - RB750_NAND_NRE | RB750_NAND_NWE | \ - RB750_NAND_NCE) + RB750_NAND_NRE | RB750_NAND_NWE) struct rb750_nand_info { struct nand_chip chip; struct mtd_info mtd; + struct rb7xx_nand_platform_data *pdata; }; +static inline struct rb750_nand_info *mtd_to_rbinfo(struct mtd_info *mtd) +{ + return container_of(mtd, struct rb750_nand_info, mtd); +} + /* * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader * will not be able to find the kernel that we load. @@ -65,7 +71,7 @@ static struct mtd_partition rb750_nand_partitions[] = { .offset = (256 * 1024), .size = (4 * 1024 * 1024) - (256 * 1024), }, { - .name = "rootfs", + .name = "ubi", .offset = MTDPART_OFS_NXTBLK, .size = MTDPART_SIZ_FULL, }, @@ -73,7 +79,7 @@ static struct mtd_partition rb750_nand_partitions[] = { static void rb750_nand_write(const u8 *buf, unsigned len) { - void __iomem *base = ar71xx_gpio_base; + void __iomem *base = ath79_gpio_base; u32 out; u32 t; unsigned i; @@ -104,10 +110,9 @@ static void rb750_nand_write(const u8 *buf, unsigned len) __raw_readl(base + AR71XX_GPIO_REG_OE); } -static int rb750_nand_read_verify(u8 *read_buf, unsigned len, - const u8 *verify_buf) +static void rb750_nand_read(u8 *read_buf, unsigned len) { - void __iomem *base = ar71xx_gpio_base; + void __iomem *base = ath79_gpio_base; unsigned i; for (i = 0; i < len; i++) { @@ -125,29 +130,18 @@ static int rb750_nand_read_verify(u8 *read_buf, unsigned len, /* deactivate RE line */ __raw_writel(RB750_NAND_NRE, base + AR71XX_GPIO_REG_SET); - if (read_buf) - read_buf[i] = data; - else if (verify_buf && verify_buf[i] != data) - return -EFAULT; + read_buf[i] = data; } - - return 0; } static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) { - void __iomem *base = ar71xx_gpio_base; - u32 func; + struct rb750_nand_info *rbinfo = mtd_to_rbinfo(mtd); + void __iomem *base = ath79_gpio_base; u32 t; - func = __raw_readl(base + AR71XX_GPIO_REG_FUNC); if (chip >= 0) { - /* disable latch */ - rb750_latch_change(RB750_LVC573_LE, 0); - - /* disable alternate functions */ - ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, - AR724X_GPIO_FUNC_SPI_EN); + rbinfo->pdata->enable_pins(); /* set input mode for data lines */ t = __raw_readl(base + AR71XX_GPIO_REG_OE); @@ -161,10 +155,12 @@ static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) (void) __raw_readl(base + AR71XX_GPIO_REG_SET); /* activate CE line */ - __raw_writel(RB750_NAND_NCE, base + AR71XX_GPIO_REG_CLEAR); + __raw_writel(rbinfo->pdata->nce_line, + base + AR71XX_GPIO_REG_CLEAR); } else { /* deactivate CE line */ - __raw_writel(RB750_NAND_NCE, base + AR71XX_GPIO_REG_SET); + __raw_writel(rbinfo->pdata->nce_line, + base + AR71XX_GPIO_REG_SET); /* flush write */ (void) __raw_readl(base + AR71XX_GPIO_REG_SET); @@ -172,18 +168,13 @@ static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) __raw_writel(t | RB750_NAND_IO0 | RB750_NAND_RDY, base + AR71XX_GPIO_REG_OE); - /* restore alternate functions */ - ar71xx_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN, - AR724X_GPIO_FUNC_JTAG_DISABLE); - - /* enable latch */ - rb750_latch_change(0, RB750_LVC573_LE); + rbinfo->pdata->disable_pins(); } } static int rb750_nand_dev_ready(struct mtd_info *mtd) { - void __iomem *base = ar71xx_gpio_base; + void __iomem *base = ath79_gpio_base; return !!(__raw_readl(base + AR71XX_GPIO_REG_IN) & RB750_NAND_RDY); } @@ -192,7 +183,7 @@ static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { if (ctrl & NAND_CTRL_CHANGE) { - void __iomem *base = ar71xx_gpio_base; + void __iomem *base = ath79_gpio_base; u32 t; t = __raw_readl(base + AR71XX_GPIO_REG_OUT); @@ -215,13 +206,13 @@ static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, static u8 rb750_nand_read_byte(struct mtd_info *mtd) { u8 data = 0; - rb750_nand_read_verify(&data, 1, NULL); + rb750_nand_read(&data, 1); return data; } static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) { - rb750_nand_read_verify(buf, len, NULL); + rb750_nand_read(buf, len); } static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) @@ -229,14 +220,9 @@ static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) rb750_nand_write(buf, len); } -static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len) -{ - return rb750_nand_read_verify(NULL, len, buf); -} - -static void __init rb750_nand_gpio_init(void) +static void __init rb750_nand_gpio_init(struct rb750_nand_info *info) { - void __iomem *base = ar71xx_gpio_base; + void __iomem *base = ath79_gpio_base; u32 out; u32 t; @@ -255,19 +241,24 @@ static void __init rb750_nand_gpio_init(void) /* setup output lines */ t = __raw_readl(base + AR71XX_GPIO_REG_OE); - __raw_writel(t | RB750_NAND_OUTPUT_BITS, base + AR71XX_GPIO_REG_OE); + t |= RB750_NAND_OUTPUT_BITS; + t |= info->pdata->nce_line; + __raw_writel(t, base + AR71XX_GPIO_REG_OE); - rb750_latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0); + info->pdata->latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0); } -static int __init rb750_nand_probe(struct platform_device *pdev) +static int rb750_nand_probe(struct platform_device *pdev) { struct rb750_nand_info *info; + struct rb7xx_nand_platform_data *pdata; int ret; printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); - rb750_nand_gpio_init(); + pdata = pdev->dev.platform_data; + if (!pdata) + return -EINVAL; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) @@ -283,14 +274,17 @@ static int __init rb750_nand_probe(struct platform_device *pdev) info->chip.read_byte = rb750_nand_read_byte; info->chip.write_buf = rb750_nand_write_buf; info->chip.read_buf = rb750_nand_read_buf; - info->chip.verify_buf = rb750_nand_verify_buf; info->chip.chip_delay = 25; info->chip.ecc.mode = NAND_ECC_SOFT; - info->chip.options |= NAND_NO_AUTOINCR; + info->chip.options = NAND_NO_SUBPAGE_WRITE; + + info->pdata = pdata; platform_set_drvdata(pdev, info); + rb750_nand_gpio_init(info); + ret = nand_scan_ident(&info->mtd, 1, NULL); if (ret) { ret = -ENXIO; @@ -306,12 +300,8 @@ static int __init rb750_nand_probe(struct platform_device *pdev) goto err_set_drvdata; } -#ifdef CONFIG_MTD_PARTITIONS - ret = add_mtd_partitions(&info->mtd, rb750_nand_partitions, + ret = mtd_device_register(&info->mtd, rb750_nand_partitions, ARRAY_SIZE(rb750_nand_partitions)); -#else - ret = add_mtd_device(&info->mtd); -#endif if (ret) goto err_release_nand; @@ -326,7 +316,7 @@ err_free_info: return ret; } -static int __devexit rb750_nand_remove(struct platform_device *pdev) +static int rb750_nand_remove(struct platform_device *pdev) { struct rb750_nand_info *info = platform_get_drvdata(pdev); @@ -339,7 +329,7 @@ static int __devexit rb750_nand_remove(struct platform_device *pdev) static struct platform_driver rb750_nand_driver = { .probe = rb750_nand_probe, - .remove = __devexit_p(rb750_nand_remove), + .remove = rb750_nand_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE,