nand: Add NAND driver for Mikrotik RB4xx series boards
Subsystems (3)
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
@@ -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
@@ -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
@@ -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
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
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