Lines Matching +full:omap2 +full:- +full:onenand
1 // SPDX-License-Identifier: GPL-2.0-only
3 * OneNAND driver for OMAP2 / OMAP3
5 * Copyright © 2005-2006 Nokia Corporation
14 #include <linux/mtd/onenand.h>
17 #include <linux/omap-gpmc.h>
21 #include <linux/dma-mapping.h>
29 #define DRIVER_NAME "omap2-onenand"
39 struct onenand_chip onenand; member
54 complete(&c->irq_done); in omap2_onenand_interrupt()
61 return readw(c->onenand.base + reg); in read_reg()
67 writew(value, c->onenand.base + reg); in write_reg()
94 return -EINVAL; in omap2_onenand_set_cfg()
126 return -EINVAL; in omap2_onenand_get_freq()
145 struct onenand_chip *this = mtd->priv; in omap2_onenand_wait()
168 while (--i) { in omap2_onenand_wait()
177 return -EIO; in omap2_onenand_wait()
196 reinit_completion(&c->irq_done); in omap2_onenand_wait()
197 result = gpiod_get_value(c->int_gpiod); in omap2_onenand_wait()
206 if (!wait_for_completion_io_timeout(&c->irq_done, in omap2_onenand_wait()
211 !this->ongoing) { in omap2_onenand_wait()
222 return -EIO; in omap2_onenand_wait()
278 mtd->ecc_stats.failed++; in omap2_onenand_wait()
279 return -EBADMSG; in omap2_onenand_wait()
284 mtd->ecc_stats.corrected++; in omap2_onenand_wait()
289 return -EIO; in omap2_onenand_wait()
297 return -EIO; in omap2_onenand_wait()
301 if (this->ongoing) in omap2_onenand_wait()
312 struct onenand_chip *this = mtd->priv; in omap2_onenand_bufferram_offset()
316 return this->writesize; in omap2_onenand_bufferram_offset()
318 return mtd->oobsize; in omap2_onenand_bufferram_offset()
331 tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, in omap2_onenand_dma_transfer()
334 dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n"); in omap2_onenand_dma_transfer()
335 return -EIO; in omap2_onenand_dma_transfer()
338 reinit_completion(&c->dma_done); in omap2_onenand_dma_transfer()
340 tx->callback = omap2_onenand_dma_complete_func; in omap2_onenand_dma_transfer()
341 tx->callback_param = &c->dma_done; in omap2_onenand_dma_transfer()
343 cookie = tx->tx_submit(tx); in omap2_onenand_dma_transfer()
345 dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n"); in omap2_onenand_dma_transfer()
346 return -EIO; in omap2_onenand_dma_transfer()
349 dma_async_issue_pending(c->dma_chan); in omap2_onenand_dma_transfer()
351 if (!wait_for_completion_io_timeout(&c->dma_done, in omap2_onenand_dma_transfer()
353 dmaengine_terminate_sync(c->dma_chan); in omap2_onenand_dma_transfer()
354 return -ETIMEDOUT; in omap2_onenand_dma_transfer()
365 struct onenand_chip *this = mtd->priv; in omap2_onenand_read_bufferram()
366 struct device *dev = &c->pdev->dev; in omap2_onenand_read_bufferram()
374 * If the buffer address is not DMA-able, len is not long enough to in omap2_onenand_read_bufferram()
379 count < 384 || mtd->oops_panic_write) in omap2_onenand_read_bufferram()
384 count -= xtra; in omap2_onenand_read_bufferram()
385 memcpy(buf + count, this->base + bram_offset + count, xtra); in omap2_onenand_read_bufferram()
389 dma_src = c->phys_base + bram_offset; in omap2_onenand_read_bufferram()
404 memcpy(buf, this->base + bram_offset, count); in omap2_onenand_read_bufferram()
413 struct onenand_chip *this = mtd->priv; in omap2_onenand_write_bufferram()
414 struct device *dev = &c->pdev->dev; in omap2_onenand_write_bufferram()
421 * If the buffer address is not DMA-able, len is not long enough to in omap2_onenand_write_bufferram()
426 count < 384 || mtd->oops_panic_write) in omap2_onenand_write_bufferram()
430 dma_dst = c->phys_base + bram_offset; in omap2_onenand_write_bufferram()
444 memcpy(this->base + bram_offset, buf, count); in omap2_onenand_write_bufferram()
450 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); in omap2_onenand_shutdown()
456 memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE); in omap2_onenand_shutdown()
467 struct device *dev = &pdev->dev; in omap2_onenand_probe()
468 struct device_node *np = dev->of_node; in omap2_onenand_probe()
478 return -ENOMEM; in omap2_onenand_probe()
480 init_completion(&c->irq_done); in omap2_onenand_probe()
481 init_completion(&c->dma_done); in omap2_onenand_probe()
482 c->gpmc_cs = val; in omap2_onenand_probe()
484 c->onenand.base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in omap2_onenand_probe()
485 if (IS_ERR(c->onenand.base)) in omap2_onenand_probe()
486 return PTR_ERR(c->onenand.base); in omap2_onenand_probe()
487 c->phys_base = res->start; in omap2_onenand_probe()
489 c->int_gpiod = devm_gpiod_get_optional(dev, "int", GPIOD_IN); in omap2_onenand_probe()
490 if (IS_ERR(c->int_gpiod)) { in omap2_onenand_probe()
492 return dev_err_probe(dev, PTR_ERR(c->int_gpiod), "error getting gpio\n"); in omap2_onenand_probe()
495 if (c->int_gpiod) { in omap2_onenand_probe()
496 r = devm_request_irq(dev, gpiod_to_irq(c->int_gpiod), in omap2_onenand_probe()
498 IRQF_TRIGGER_RISING, "onenand", c); in omap2_onenand_probe()
502 c->onenand.wait = omap2_onenand_wait; in omap2_onenand_probe()
508 c->dma_chan = dma_request_channel(mask, NULL, NULL); in omap2_onenand_probe()
509 if (c->dma_chan) { in omap2_onenand_probe()
510 c->onenand.read_bufferram = omap2_onenand_read_bufferram; in omap2_onenand_probe()
511 c->onenand.write_bufferram = omap2_onenand_write_bufferram; in omap2_onenand_probe()
514 c->pdev = pdev; in omap2_onenand_probe()
515 c->mtd.priv = &c->onenand; in omap2_onenand_probe()
516 c->mtd.dev.parent = dev; in omap2_onenand_probe()
517 mtd_set_of_node(&c->mtd, dev->of_node); in omap2_onenand_probe()
520 c->gpmc_cs, c->phys_base, c->onenand.base, in omap2_onenand_probe()
521 c->dma_chan ? "DMA" : "PIO"); in omap2_onenand_probe()
523 r = onenand_scan(&c->mtd, 1); in omap2_onenand_probe()
527 freq = omap2_onenand_get_freq(c->onenand.version_id); in omap2_onenand_probe()
547 r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs, in omap2_onenand_probe()
561 r = mtd_device_register(&c->mtd, NULL, 0); in omap2_onenand_probe()
570 onenand_release(&c->mtd); in omap2_onenand_probe()
572 if (c->dma_chan) in omap2_onenand_probe()
573 dma_release_channel(c->dma_chan); in omap2_onenand_probe()
580 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); in omap2_onenand_remove()
582 onenand_release(&c->mtd); in omap2_onenand_remove()
583 if (c->dma_chan) in omap2_onenand_remove()
584 dma_release_channel(c->dma_chan); in omap2_onenand_remove()
589 { .compatible = "ti,omap2-onenand", },
609 MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP2 / OMAP3");