Skip to contentSkip to conversation

nand: Add NAND driver for Mikrotik RB4xx series boards

PATCH Superseded Bert Vermeulen 2 participants 3 messages May 7, 2015 – May 8, 2015

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 nand: Add NAND driver for Mikrotik RB4xx series boards

The NAND chip containing the root filesystem is behind an SPI-connected CPLD. This driver uses the spi-rb4xx driver to communicate with the CPLD.

The CPLD also acts as a GPIO expander: the ALE/CLE/NCE pins are set via CPLD commands. Some LEDs on the board are also accessed this way.

---
Changes in v2:
- Fix Kconfig dependencies and description
- Move NAND partitions into platform data
- Use gpiod API with lookup table, and devm_ as needed
- Code cleanup

 arch/mips/include/asm/mach-ath79/rb4xx.h |  44 +++
 drivers/mtd/nand/Kconfig                 |   7 +
 drivers/mtd/nand/Makefile                |   1 +
 drivers/mtd/nand/rb4xx_nand.c            | 482 +++++++++++++++++++++++++++++++
 4 files changed, 534 insertions(+)
 create mode 100644 arch/mips/include/asm/mach-ath79/rb4xx.h
 create mode 100644 drivers/mtd/nand/rb4xx_nand.c
arch/mips/include/asm/mach-ath79/rb4xx.h new file +44 -0
new file mode 100644
index 0000000..667ea748
@@ -0,0 +1,44 @@
+/*
+ * SPI driver definitions for the CPLD chip on the Mikrotik RB4xx boards
+ *
+ * Copyright (C) 2010 Gabor Juhos <[email protected]>
+ *
+ * This file was based on the patches for Linux 2.6.27.39 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/spi/flash.h>
+
+#define RB4XX_GPIO_CPLD_BASE	32
+
+#define CPLD_GPIO_LED1		0
+#define CPLD_GPIO_LED2		2
+#define CPLD_GPIO_LED3		1
+#define CPLD_GPIO_LED4		3
+#define CPLD_GPIO_FAN		4
+#define CPLD_GPIO_ALE		5
+#define CPLD_GPIO_CLE		6
+#define CPLD_GPIO_NCE		7
+#define CPLD_GPIO_LED5		8
+
+#define CPLD_NUM_GPIOS		9
+
+#define CPLD_CFG_LED1		BIT(CPLD_GPIO_LED1)
+#define CPLD_CFG_LED2		BIT(CPLD_GPIO_LED2)
+#define CPLD_CFG_LED3		BIT(CPLD_GPIO_LED3)
+#define CPLD_CFG_LED4		BIT(CPLD_GPIO_LED4)
+#define CPLD_CFG_FAN		BIT(CPLD_GPIO_FAN)
+#define CPLD_CFG_ALE		BIT(CPLD_GPIO_ALE)
+#define CPLD_CFG_CLE		BIT(CPLD_GPIO_CLE)
+#define CPLD_CFG_NCE		BIT(CPLD_GPIO_NCE)
+#define CPLD_CFG_LED5		BIT(CPLD_GPIO_LED5)
+
+struct rb4xx_cpld_platform_data {
+	unsigned gpio_base;
+	struct flash_platform_data flash_data;
+};
+
drivers/mtd/nand/Kconfig +7 -0
index 5897d8d..873639f 100644
@@ -530,4 +530,11 @@ config MTD_NAND_HISI504
 	help
 	  Enables support for NAND controller on Hisilicon SoC Hip04.
 
+config MTD_NAND_RB4XX
+	tristate "NAND flash driver for Mikrotik RB4xx series boards"
+	depends on MTD_NAND && SPI_RB4XX
+	help
+	  Enables support for the NAND flash chip on Mikrotik Routerboard
+	  RB4xx series.
+
 endif # MTD_NAND
drivers/mtd/nand/Makefile +1 -0
index 582bbd05..56dbd08 100644
@@ -52,5 +52,6 @@ obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
 obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
 obj-$(CONFIG_MTD_NAND_SUNXI)		+= sunxi_nand.o
 obj-$(CONFIG_MTD_NAND_HISI504)	        += hisi504_nand.o
+obj-$(CONFIG_MTD_NAND_RB4XX)	        += rb4xx_nand.o
 
 nand-objs := nand_base.o nand_bbt.o nand_timings.o
drivers/mtd/nand/rb4xx_nand.c new file +482 -0

482 lines not on this page · raw message

Signature · 1 line
1.9.1
#1 lore raw
Quoted 53 lines · Bert Vermeulen
drivers/mtd/nand/rb4xx_nand.c new file +53 -0
+static int rb4xx_nand_probe(struct platform_device *pdev)
+{
+       struct device *spi_dev;
+       struct rb4xx_nand_info  *info;
+       struct rb4xx_cpld_platform_data *pdata;
+       int ret;
+
+       /*
+        * NAND chip is behind the CPLD on SPI bus 0 CS 1. Allow this
+        * to silently fail the second time around.
+        */
+       spi_register_driver(&rb4xx_cpld_driver);
+
+       /*
+        * Getting a handle on the SPI device above will fail the first time,
+        * but should succeed whenever that driver gets probed.
+        */
+       spi_dev = bus_find_device_by_name(&spi_bus_type, NULL, "spi0.1");
+       if (!spi_dev)
+               return -EPROBE_DEFER;
+
+       pdata = dev_get_platdata(spi_dev);
+       if (!pdata)
+               return -ENODATA;
+
+       info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->gpio_ale = devm_gpiod_get(&pdev->dev, "NAND ALE", GPIOD_OUT_LOW);
+       if (IS_ERR(info->gpio_ale)) {
+               dev_err(&pdev->dev, "unable to request gpio NAND ALE: %ld\n",
+                       PTR_ERR(info->gpio_ale));
+               return -ENOENT;
+       }
+
+       info->gpio_cle = devm_gpiod_get(&pdev->dev, "NAND CLE", GPIOD_OUT_LOW);
+       if (IS_ERR(info->gpio_cle)) {
+               dev_err(&pdev->dev, "unable to request gpio NAND CLE: %ld\n",
+                       PTR_ERR(info->gpio_cle));
+               return -ENOENT;
+       }
+
+       info->gpio_nce = devm_gpiod_get(&pdev->dev, "NAND NCE", GPIOD_OUT_LOW);
+       if (IS_ERR(info->gpio_nce)) {
+               dev_err(&pdev->dev, "unable to request gpio NAND NCE: %ld\n",
+                       PTR_ERR(info->gpio_nce));
+               return -ENOENT;
+       }
+
+       /* Platform GPIO, has no device to manage it. */
+       info->gpio_rdy = gpiod_get(NULL, "NAND RDY", GPIOD_IN);
+       if (IS_ERR(info->gpio_rdy)) {

drivers/mtd/nand/rb4xx_nand.c line 414

Quoted 10 lines
drivers/mtd/nand/rb4xx_nand.c new file +10 -0
+               dev_err(&pdev->dev, "unable to request gpio RDY: %ld\n",
+                       PTR_ERR(info->gpio_rdy));
+               return -ENOENT;
+       }
+
+       info->spi_dev = container_of(spi_dev, struct spi_device, dev);
+
+       info->chip.priv = info;
+       info->mtd.priv  = &info->chip;
+       info->mtd.owner = THIS_MODULE;

If you should respin, could you add

info->mtd.dev.parent = &pdev->dev;

This will have a symlink to the parent device show up in sysfs. Seems some people feel rather strongly about that.

Thanks,
Frans

#2 lore raw
Quoted 6 lines · Frans Klaver

drivers/mtd/nand/rb4xx_nand.c line 414

Quoted 4 lines · Bert Vermeulen
drivers/mtd/nand/rb4xx_nand.c new file +4 -0
+
+       info->chip.priv = info;
+       info->mtd.priv  = &info->chip;
+       info->mtd.owner = THIS_MODULE;
Quoted 6 lines

If you should respin, could you add

info->mtd.dev.parent = &pdev->dev;

This will have a symlink to the parent device show up in sysfs. Seems some people feel rather strongly about that.

Sure, will do. I'll wait for some comment from David Woodhouse or Brian Norris first, in case there's something more substantial to fix as well.

Signature · 1 line
Bert Vermeulen        [email protected]          email/xmpp