linux/drivers/mtd/nand/gpio.c
<<
>>
Prefs
   1/*
   2 * drivers/mtd/nand/gpio.c
   3 *
   4 * Updated, and converted to generic GPIO based driver by Russell King.
   5 *
   6 * Written by Ben Dooks <ben@simtec.co.uk>
   7 *   Based on 2.4 version by Mark Whittaker
   8 *
   9 * © 2004 Simtec Electronics
  10 *
  11 * Device driver for NAND connected via GPIO
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License version 2 as
  15 * published by the Free Software Foundation.
  16 *
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/init.h>
  21#include <linux/slab.h>
  22#include <linux/module.h>
  23#include <linux/platform_device.h>
  24#include <linux/gpio.h>
  25#include <linux/io.h>
  26#include <linux/mtd/mtd.h>
  27#include <linux/mtd/nand.h>
  28#include <linux/mtd/partitions.h>
  29#include <linux/mtd/nand-gpio.h>
  30#include <linux/of.h>
  31#include <linux/of_address.h>
  32#include <linux/of_gpio.h>
  33
  34struct gpiomtd {
  35        void __iomem            *io_sync;
  36        struct mtd_info         mtd_info;
  37        struct nand_chip        nand_chip;
  38        struct gpio_nand_platdata plat;
  39};
  40
  41#define gpio_nand_getpriv(x) container_of(x, struct gpiomtd, mtd_info)
  42
  43
  44#ifdef CONFIG_ARM
  45/* gpio_nand_dosync()
  46 *
  47 * Make sure the GPIO state changes occur in-order with writes to NAND
  48 * memory region.
  49 * Needed on PXA due to bus-reordering within the SoC itself (see section on
  50 * I/O ordering in PXA manual (section 2.3, p35)
  51 */
  52static void gpio_nand_dosync(struct gpiomtd *gpiomtd)
  53{
  54        unsigned long tmp;
  55
  56        if (gpiomtd->io_sync) {
  57                /*
  58                 * Linux memory barriers don't cater for what's required here.
  59                 * What's required is what's here - a read from a separate
  60                 * region with a dependency on that read.
  61                 */
  62                tmp = readl(gpiomtd->io_sync);
  63                asm volatile("mov %1, %0\n" : "=r" (tmp) : "r" (tmp));
  64        }
  65}
  66#else
  67static inline void gpio_nand_dosync(struct gpiomtd *gpiomtd) {}
  68#endif
  69
  70static void gpio_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
  71{
  72        struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
  73
  74        gpio_nand_dosync(gpiomtd);
  75
  76        if (ctrl & NAND_CTRL_CHANGE) {
  77                gpio_set_value(gpiomtd->plat.gpio_nce, !(ctrl & NAND_NCE));
  78                gpio_set_value(gpiomtd->plat.gpio_cle, !!(ctrl & NAND_CLE));
  79                gpio_set_value(gpiomtd->plat.gpio_ale, !!(ctrl & NAND_ALE));
  80                gpio_nand_dosync(gpiomtd);
  81        }
  82        if (cmd == NAND_CMD_NONE)
  83                return;
  84
  85        writeb(cmd, gpiomtd->nand_chip.IO_ADDR_W);
  86        gpio_nand_dosync(gpiomtd);
  87}
  88
  89static void gpio_nand_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
  90{
  91        struct nand_chip *this = mtd->priv;
  92
  93        iowrite8_rep(this->IO_ADDR_W, buf, len);
  94}
  95
  96static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len)
  97{
  98        struct nand_chip *this = mtd->priv;
  99
 100        ioread8_rep(this->IO_ADDR_R, buf, len);
 101}
 102
 103static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf,
 104                                 int len)
 105{
 106        struct nand_chip *this = mtd->priv;
 107
 108        if (IS_ALIGNED((unsigned long)buf, 2)) {
 109                iowrite16_rep(this->IO_ADDR_W, buf, len>>1);
 110        } else {
 111                int i;
 112                unsigned short *ptr = (unsigned short *)buf;
 113
 114                for (i = 0; i < len; i += 2, ptr++)
 115                        writew(*ptr, this->IO_ADDR_W);
 116        }
 117}
 118
 119static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)
 120{
 121        struct nand_chip *this = mtd->priv;
 122
 123        if (IS_ALIGNED((unsigned long)buf, 2)) {
 124                ioread16_rep(this->IO_ADDR_R, buf, len>>1);
 125        } else {
 126                int i;
 127                unsigned short *ptr = (unsigned short *)buf;
 128
 129                for (i = 0; i < len; i += 2, ptr++)
 130                        *ptr = readw(this->IO_ADDR_R);
 131        }
 132}
 133
 134static int gpio_nand_devready(struct mtd_info *mtd)
 135{
 136        struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
 137
 138        if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
 139                return gpio_get_value(gpiomtd->plat.gpio_rdy);
 140
 141        return 1;
 142}
 143
 144#ifdef CONFIG_OF
 145static const struct of_device_id gpio_nand_id_table[] = {
 146        { .compatible = "gpio-control-nand" },
 147        {}
 148};
 149MODULE_DEVICE_TABLE(of, gpio_nand_id_table);
 150
 151static int gpio_nand_get_config_of(const struct device *dev,
 152                                   struct gpio_nand_platdata *plat)
 153{
 154        u32 val;
 155
 156        if (!of_property_read_u32(dev->of_node, "bank-width", &val)) {
 157                if (val == 2) {
 158                        plat->options |= NAND_BUSWIDTH_16;
 159                } else if (val != 1) {
 160                        dev_err(dev, "invalid bank-width %u\n", val);
 161                        return -EINVAL;
 162                }
 163        }
 164
 165        plat->gpio_rdy = of_get_gpio(dev->of_node, 0);
 166        plat->gpio_nce = of_get_gpio(dev->of_node, 1);
 167        plat->gpio_ale = of_get_gpio(dev->of_node, 2);
 168        plat->gpio_cle = of_get_gpio(dev->of_node, 3);
 169        plat->gpio_nwp = of_get_gpio(dev->of_node, 4);
 170
 171        if (!of_property_read_u32(dev->of_node, "chip-delay", &val))
 172                plat->chip_delay = val;
 173
 174        return 0;
 175}
 176
 177static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev)
 178{
 179        struct resource *r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL);
 180        u64 addr;
 181
 182        if (!r || of_property_read_u64(pdev->dev.of_node,
 183                                       "gpio-control-nand,io-sync-reg", &addr))
 184                return NULL;
 185
 186        r->start = addr;
 187        r->end = r->start + 0x3;
 188        r->flags = IORESOURCE_MEM;
 189
 190        return r;
 191}
 192#else /* CONFIG_OF */
 193#define gpio_nand_id_table NULL
 194static inline int gpio_nand_get_config_of(const struct device *dev,
 195                                          struct gpio_nand_platdata *plat)
 196{
 197        return -ENOSYS;
 198}
 199
 200static inline struct resource *
 201gpio_nand_get_io_sync_of(struct platform_device *pdev)
 202{
 203        return NULL;
 204}
 205#endif /* CONFIG_OF */
 206
 207static inline int gpio_nand_get_config(const struct device *dev,
 208                                       struct gpio_nand_platdata *plat)
 209{
 210        int ret = gpio_nand_get_config_of(dev, plat);
 211
 212        if (!ret)
 213                return ret;
 214
 215        if (dev->platform_data) {
 216                memcpy(plat, dev->platform_data, sizeof(*plat));
 217                return 0;
 218        }
 219
 220        return -EINVAL;
 221}
 222
 223static inline struct resource *
 224gpio_nand_get_io_sync(struct platform_device *pdev)
 225{
 226        struct resource *r = gpio_nand_get_io_sync_of(pdev);
 227
 228        if (r)
 229                return r;
 230
 231        return platform_get_resource(pdev, IORESOURCE_MEM, 1);
 232}
 233
 234static int gpio_nand_remove(struct platform_device *dev)
 235{
 236        struct gpiomtd *gpiomtd = platform_get_drvdata(dev);
 237        struct resource *res;
 238
 239        nand_release(&gpiomtd->mtd_info);
 240
 241        res = gpio_nand_get_io_sync(dev);
 242        iounmap(gpiomtd->io_sync);
 243        if (res)
 244                release_mem_region(res->start, resource_size(res));
 245
 246        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 247        iounmap(gpiomtd->nand_chip.IO_ADDR_R);
 248        release_mem_region(res->start, resource_size(res));
 249
 250        if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
 251                gpio_set_value(gpiomtd->plat.gpio_nwp, 0);
 252        gpio_set_value(gpiomtd->plat.gpio_nce, 1);
 253
 254        gpio_free(gpiomtd->plat.gpio_cle);
 255        gpio_free(gpiomtd->plat.gpio_ale);
 256        gpio_free(gpiomtd->plat.gpio_nce);
 257        if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
 258                gpio_free(gpiomtd->plat.gpio_nwp);
 259        if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
 260                gpio_free(gpiomtd->plat.gpio_rdy);
 261
 262        kfree(gpiomtd);
 263
 264        return 0;
 265}
 266
 267static void __iomem *request_and_remap(struct resource *res, size_t size,
 268                                        const char *name, int *err)
 269{
 270        void __iomem *ptr;
 271
 272        if (!request_mem_region(res->start, resource_size(res), name)) {
 273                *err = -EBUSY;
 274                return NULL;
 275        }
 276
 277        ptr = ioremap(res->start, size);
 278        if (!ptr) {
 279                release_mem_region(res->start, resource_size(res));
 280                *err = -ENOMEM;
 281        }
 282        return ptr;
 283}
 284
 285static int gpio_nand_probe(struct platform_device *dev)
 286{
 287        struct gpiomtd *gpiomtd;
 288        struct nand_chip *this;
 289        struct resource *res0, *res1;
 290        struct mtd_part_parser_data ppdata = {};
 291        int ret = 0;
 292
 293        if (!dev->dev.of_node && !dev->dev.platform_data)
 294                return -EINVAL;
 295
 296        res0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
 297        if (!res0)
 298                return -EINVAL;
 299
 300        gpiomtd = kzalloc(sizeof(*gpiomtd), GFP_KERNEL);
 301        if (gpiomtd == NULL) {
 302                dev_err(&dev->dev, "failed to create NAND MTD\n");
 303                return -ENOMEM;
 304        }
 305
 306        this = &gpiomtd->nand_chip;
 307        this->IO_ADDR_R = request_and_remap(res0, 2, "NAND", &ret);
 308        if (!this->IO_ADDR_R) {
 309                dev_err(&dev->dev, "unable to map NAND\n");
 310                goto err_map;
 311        }
 312
 313        res1 = gpio_nand_get_io_sync(dev);
 314        if (res1) {
 315                gpiomtd->io_sync = request_and_remap(res1, 4, "NAND sync", &ret);
 316                if (!gpiomtd->io_sync) {
 317                        dev_err(&dev->dev, "unable to map sync NAND\n");
 318                        goto err_sync;
 319                }
 320        }
 321
 322        ret = gpio_nand_get_config(&dev->dev, &gpiomtd->plat);
 323        if (ret)
 324                goto err_nce;
 325
 326        ret = gpio_request(gpiomtd->plat.gpio_nce, "NAND NCE");
 327        if (ret)
 328                goto err_nce;
 329        gpio_direction_output(gpiomtd->plat.gpio_nce, 1);
 330        if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) {
 331                ret = gpio_request(gpiomtd->plat.gpio_nwp, "NAND NWP");
 332                if (ret)
 333                        goto err_nwp;
 334                gpio_direction_output(gpiomtd->plat.gpio_nwp, 1);
 335        }
 336        ret = gpio_request(gpiomtd->plat.gpio_ale, "NAND ALE");
 337        if (ret)
 338                goto err_ale;
 339        gpio_direction_output(gpiomtd->plat.gpio_ale, 0);
 340        ret = gpio_request(gpiomtd->plat.gpio_cle, "NAND CLE");
 341        if (ret)
 342                goto err_cle;
 343        gpio_direction_output(gpiomtd->plat.gpio_cle, 0);
 344        if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) {
 345                ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY");
 346                if (ret)
 347                        goto err_rdy;
 348                gpio_direction_input(gpiomtd->plat.gpio_rdy);
 349        }
 350
 351
 352        this->IO_ADDR_W  = this->IO_ADDR_R;
 353        this->ecc.mode   = NAND_ECC_SOFT;
 354        this->options    = gpiomtd->plat.options;
 355        this->chip_delay = gpiomtd->plat.chip_delay;
 356
 357        /* install our routines */
 358        this->cmd_ctrl   = gpio_nand_cmd_ctrl;
 359        this->dev_ready  = gpio_nand_devready;
 360
 361        if (this->options & NAND_BUSWIDTH_16) {
 362                this->read_buf   = gpio_nand_readbuf16;
 363                this->write_buf  = gpio_nand_writebuf16;
 364        } else {
 365                this->read_buf   = gpio_nand_readbuf;
 366                this->write_buf  = gpio_nand_writebuf;
 367        }
 368
 369        /* set the mtd private data for the nand driver */
 370        gpiomtd->mtd_info.priv = this;
 371        gpiomtd->mtd_info.owner = THIS_MODULE;
 372
 373        if (nand_scan(&gpiomtd->mtd_info, 1)) {
 374                dev_err(&dev->dev, "no nand chips found?\n");
 375                ret = -ENXIO;
 376                goto err_wp;
 377        }
 378
 379        if (gpiomtd->plat.adjust_parts)
 380                gpiomtd->plat.adjust_parts(&gpiomtd->plat,
 381                                           gpiomtd->mtd_info.size);
 382
 383        ppdata.of_node = dev->dev.of_node;
 384        ret = mtd_device_parse_register(&gpiomtd->mtd_info, NULL, &ppdata,
 385                                        gpiomtd->plat.parts,
 386                                        gpiomtd->plat.num_parts);
 387        if (ret)
 388                goto err_wp;
 389        platform_set_drvdata(dev, gpiomtd);
 390
 391        return 0;
 392
 393err_wp:
 394        if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
 395                gpio_set_value(gpiomtd->plat.gpio_nwp, 0);
 396        if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
 397                gpio_free(gpiomtd->plat.gpio_rdy);
 398err_rdy:
 399        gpio_free(gpiomtd->plat.gpio_cle);
 400err_cle:
 401        gpio_free(gpiomtd->plat.gpio_ale);
 402err_ale:
 403        if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
 404                gpio_free(gpiomtd->plat.gpio_nwp);
 405err_nwp:
 406        gpio_free(gpiomtd->plat.gpio_nce);
 407err_nce:
 408        iounmap(gpiomtd->io_sync);
 409        if (res1)
 410                release_mem_region(res1->start, resource_size(res1));
 411err_sync:
 412        iounmap(gpiomtd->nand_chip.IO_ADDR_R);
 413        release_mem_region(res0->start, resource_size(res0));
 414err_map:
 415        kfree(gpiomtd);
 416        return ret;
 417}
 418
 419static struct platform_driver gpio_nand_driver = {
 420        .probe          = gpio_nand_probe,
 421        .remove         = gpio_nand_remove,
 422        .driver         = {
 423                .name   = "gpio-nand",
 424                .of_match_table = gpio_nand_id_table,
 425        },
 426};
 427
 428module_platform_driver(gpio_nand_driver);
 429
 430MODULE_LICENSE("GPL");
 431MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 432MODULE_DESCRIPTION("GPIO NAND Driver");
 433