diff options
Diffstat (limited to 'target/mips/mikrotik-rb4xx/patches/3.14.54/0001-mtd-add-rb4xx-nand-driver.patch')
-rw-r--r-- | target/mips/mikrotik-rb4xx/patches/3.14.54/0001-mtd-add-rb4xx-nand-driver.patch | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/target/mips/mikrotik-rb4xx/patches/3.14.54/0001-mtd-add-rb4xx-nand-driver.patch b/target/mips/mikrotik-rb4xx/patches/3.14.54/0001-mtd-add-rb4xx-nand-driver.patch deleted file mode 100644 index 8199de991..000000000 --- a/target/mips/mikrotik-rb4xx/patches/3.14.54/0001-mtd-add-rb4xx-nand-driver.patch +++ /dev/null @@ -1,351 +0,0 @@ -From 1e692cc0c53202b932eedabd0315107910c5b093 Mon Sep 17 00:00:00 2001 -From: Phil Sutter <phil@nwl.cc> -Date: Tue, 13 May 2014 00:08:54 +0200 -Subject: [PATCH] mtd: add rb4xx nand driver - ---- - drivers/mtd/nand/Kconfig | 4 + - drivers/mtd/nand/Makefile | 1 + - drivers/mtd/nand/rb4xx_nand.c | 305 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 310 insertions(+) - create mode 100644 drivers/mtd/nand/rb4xx_nand.c - -diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -index 90ff447..bb01309 100644 ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -510,4 +510,8 @@ config MTD_NAND_XWAY - Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached - to the External Bus Unit (EBU). - -+config MTD_NAND_RB4XX -+ tristate "NAND flash driver for RouterBoard 4xx series" -+ depends on MTD_NAND && ATH79_MACH_RB4XX -+ - endif # MTD_NAND -diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index 542b568..e2b5e1c 100644 ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -31,6 +31,7 @@ obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o - obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o - obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o - obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o -+obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o - obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o - obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o - obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o -diff --git a/drivers/mtd/nand/rb4xx_nand.c b/drivers/mtd/nand/rb4xx_nand.c -new file mode 100644 -index 0000000..5b9841b ---- /dev/null -+++ b/drivers/mtd/nand/rb4xx_nand.c -@@ -0,0 +1,305 @@ -+/* -+ * NAND flash driver for the MikroTik RouterBoard 4xx series -+ * -+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * This file was based on the driver for Linux 2.6.22 published by -+ * MikroTik for their RouterBoard 4xx series devices. -+ * -+ * 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/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/mtd/nand.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/partitions.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+#include <linux/io.h> -+#include <linux/gpio.h> -+#include <linux/slab.h> -+ -+#include <asm/mach-ath79/ath79.h> -+#include <asm/mach-ath79/rb4xx_cpld.h> -+ -+#define DRV_NAME "rb4xx-nand" -+#define DRV_VERSION "0.2.0" -+#define DRV_DESC "NAND flash driver for RouterBoard 4xx series" -+ -+#define RB4XX_NAND_GPIO_READY 5 -+#define RB4XX_NAND_GPIO_ALE 37 -+#define RB4XX_NAND_GPIO_CLE 38 -+#define RB4XX_NAND_GPIO_NCE 39 -+ -+struct rb4xx_nand_info { -+ struct nand_chip chip; -+ struct mtd_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. -+ */ -+static struct nand_ecclayout rb4xx_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+static struct mtd_partition rb4xx_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "rootfs", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static int rb4xx_nand_dev_ready(struct mtd_info *mtd) -+{ -+ return gpio_get_value_cansleep(RB4XX_NAND_GPIO_READY); -+} -+ -+static void rb4xx_nand_write_cmd(unsigned char cmd) -+{ -+ unsigned char data = cmd; -+ int err; -+ -+ err = rb4xx_cpld_write(&data, 1); -+ if (err) -+ pr_err("rb4xx_nand: write cmd failed, err=%d\n", err); -+} -+ -+static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_CLE, -+ (ctrl & NAND_CLE) ? 1 : 0); -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_ALE, -+ (ctrl & NAND_ALE) ? 1 : 0); -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_NCE, -+ (ctrl & NAND_NCE) ? 0 : 1); -+ } -+ -+ if (cmd != NAND_CMD_NONE) -+ rb4xx_nand_write_cmd(cmd); -+} -+ -+static unsigned char rb4xx_nand_read_byte(struct mtd_info *mtd) -+{ -+ unsigned char data = 0; -+ int err; -+ -+ err = rb4xx_cpld_read(&data, NULL, 1); -+ if (err) { -+ pr_err("rb4xx_nand: read data failed, err=%d\n", err); -+ data = 0xff; -+ } -+ -+ return data; -+} -+ -+static void rb4xx_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf, -+ int len) -+{ -+ int err; -+ -+ err = rb4xx_cpld_write(buf, len); -+ if (err) -+ pr_err("rb4xx_nand: write buf failed, err=%d\n", err); -+} -+ -+static void rb4xx_nand_read_buf(struct mtd_info *mtd, unsigned char *buf, -+ int len) -+{ -+ int err; -+ -+ err = rb4xx_cpld_read(buf, NULL, len); -+ if (err) -+ pr_err("rb4xx_nand: read buf failed, err=%d\n", err); -+} -+ -+static int rb4xx_nand_probe(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info; -+ int ret; -+ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_READY, "NAND RDY"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_READY); -+ goto err; -+ } -+ -+ ret = gpio_direction_input(RB4XX_NAND_GPIO_READY); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set input mode on gpio %d\n", -+ RB4XX_NAND_GPIO_READY); -+ goto err_free_gpio_ready; -+ } -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_ALE, "NAND ALE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_ready; -+ } -+ -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_ALE, 0); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_ale; -+ } -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_CLE, "NAND CLE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_CLE); -+ goto err_free_gpio_ale; -+ } -+ -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_CLE, 0); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_CLE); -+ goto err_free_gpio_cle; -+ } -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_NCE, "NAND NCE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_NCE); -+ goto err_free_gpio_cle; -+ } -+ -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_NCE, 1); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_nce; -+ } -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) { -+ dev_err(&pdev->dev, "rb4xx-nand: no memory for private data\n"); -+ ret = -ENOMEM; -+ goto err_free_gpio_nce; -+ } -+ -+ info->chip.priv = &info; -+ info->mtd.priv = &info->chip; -+ info->mtd.owner = THIS_MODULE; -+ -+ info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl; -+ info->chip.dev_ready = rb4xx_nand_dev_ready; -+ info->chip.read_byte = rb4xx_nand_read_byte; -+ info->chip.write_buf = rb4xx_nand_write_buf; -+ info->chip.read_buf = rb4xx_nand_read_buf; -+ -+ info->chip.chip_delay = 25; -+ info->chip.ecc.mode = NAND_ECC_SOFT; -+ -+ platform_set_drvdata(pdev, info); -+ -+ ret = nand_scan_ident(&info->mtd, 1, NULL); -+ if (ret) { -+ ret = -ENXIO; -+ goto err_free_info; -+ } -+ -+ if (info->mtd.writesize == 512) -+ info->chip.ecc.layout = &rb4xx_nand_ecclayout; -+ -+ ret = nand_scan_tail(&info->mtd); -+ if (ret) { -+ return -ENXIO; -+ goto err_set_drvdata; -+ } -+ -+ mtd_device_register(&info->mtd, rb4xx_nand_partitions, -+ ARRAY_SIZE(rb4xx_nand_partitions)); -+ if (ret) -+ goto err_release_nand; -+ -+ return 0; -+ -+err_release_nand: -+ nand_release(&info->mtd); -+err_set_drvdata: -+ platform_set_drvdata(pdev, NULL); -+err_free_info: -+ kfree(info); -+err_free_gpio_nce: -+ gpio_free(RB4XX_NAND_GPIO_NCE); -+err_free_gpio_cle: -+ gpio_free(RB4XX_NAND_GPIO_CLE); -+err_free_gpio_ale: -+ gpio_free(RB4XX_NAND_GPIO_ALE); -+err_free_gpio_ready: -+ gpio_free(RB4XX_NAND_GPIO_READY); -+err: -+ return ret; -+} -+ -+static int rb4xx_nand_remove(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info = platform_get_drvdata(pdev); -+ -+ nand_release(&info->mtd); -+ platform_set_drvdata(pdev, NULL); -+ kfree(info); -+ gpio_free(RB4XX_NAND_GPIO_NCE); -+ gpio_free(RB4XX_NAND_GPIO_CLE); -+ gpio_free(RB4XX_NAND_GPIO_ALE); -+ gpio_free(RB4XX_NAND_GPIO_READY); -+ -+ return 0; -+} -+ -+static struct platform_driver rb4xx_nand_driver = { -+ .probe = rb4xx_nand_probe, -+ .remove = rb4xx_nand_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init rb4xx_nand_init(void) -+{ -+ return platform_driver_register(&rb4xx_nand_driver); -+} -+ -+static void __exit rb4xx_nand_exit(void) -+{ -+ platform_driver_unregister(&rb4xx_nand_driver); -+} -+ -+module_init(rb4xx_nand_init); -+module_exit(rb4xx_nand_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>"); -+MODULE_LICENSE("GPL v2"); --- -1.8.5.3 - |