.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Driver for NAND MLC Controller in LPC32xx |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * |
---|
6 | 7 | * Copyright © 2011 WORK Microwave GmbH |
---|
7 | 8 | * Copyright © 2011, 2012 Roland Stigge |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License as published by |
---|
11 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
12 | | - * (at your option) any later version. |
---|
13 | | - * |
---|
14 | | - * This program is distributed in the hope that it will be useful, |
---|
15 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
17 | | - * GNU General Public License for more details. |
---|
18 | | - * |
---|
19 | 9 | * |
---|
20 | 10 | * NAND Flash Controller Operation: |
---|
21 | 11 | * - Read: Auto Decode |
---|
.. | .. |
---|
286 | 276 | /* |
---|
287 | 277 | * Hardware specific access to control lines |
---|
288 | 278 | */ |
---|
289 | | -static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
---|
| 279 | +static void lpc32xx_nand_cmd_ctrl(struct nand_chip *nand_chip, int cmd, |
---|
290 | 280 | unsigned int ctrl) |
---|
291 | 281 | { |
---|
292 | | - struct nand_chip *nand_chip = mtd_to_nand(mtd); |
---|
293 | 282 | struct lpc32xx_nand_host *host = nand_get_controller_data(nand_chip); |
---|
294 | 283 | |
---|
295 | 284 | if (cmd != NAND_CMD_NONE) { |
---|
.. | .. |
---|
303 | 292 | /* |
---|
304 | 293 | * Read Device Ready (NAND device _and_ controller ready) |
---|
305 | 294 | */ |
---|
306 | | -static int lpc32xx_nand_device_ready(struct mtd_info *mtd) |
---|
| 295 | +static int lpc32xx_nand_device_ready(struct nand_chip *nand_chip) |
---|
307 | 296 | { |
---|
308 | | - struct nand_chip *nand_chip = mtd_to_nand(mtd); |
---|
309 | 297 | struct lpc32xx_nand_host *host = nand_get_controller_data(nand_chip); |
---|
310 | 298 | |
---|
311 | 299 | if ((readb(MLC_ISR(host->io_base)) & |
---|
.. | .. |
---|
330 | 318 | return IRQ_HANDLED; |
---|
331 | 319 | } |
---|
332 | 320 | |
---|
333 | | -static int lpc32xx_waitfunc_nand(struct mtd_info *mtd, struct nand_chip *chip) |
---|
| 321 | +static int lpc32xx_waitfunc_nand(struct nand_chip *chip) |
---|
334 | 322 | { |
---|
| 323 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
335 | 324 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
---|
336 | 325 | |
---|
337 | 326 | if (readb(MLC_ISR(host->io_base)) & MLCISR_NAND_READY) |
---|
.. | .. |
---|
349 | 338 | return NAND_STATUS_READY; |
---|
350 | 339 | } |
---|
351 | 340 | |
---|
352 | | -static int lpc32xx_waitfunc_controller(struct mtd_info *mtd, |
---|
353 | | - struct nand_chip *chip) |
---|
| 341 | +static int lpc32xx_waitfunc_controller(struct nand_chip *chip) |
---|
354 | 342 | { |
---|
| 343 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
355 | 344 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
---|
356 | 345 | |
---|
357 | 346 | if (readb(MLC_ISR(host->io_base)) & MLCISR_CONTROLLER_READY) |
---|
.. | .. |
---|
369 | 358 | return NAND_STATUS_READY; |
---|
370 | 359 | } |
---|
371 | 360 | |
---|
372 | | -static int lpc32xx_waitfunc(struct mtd_info *mtd, struct nand_chip *chip) |
---|
| 361 | +static int lpc32xx_waitfunc(struct nand_chip *chip) |
---|
373 | 362 | { |
---|
374 | | - lpc32xx_waitfunc_nand(mtd, chip); |
---|
375 | | - lpc32xx_waitfunc_controller(mtd, chip); |
---|
| 363 | + lpc32xx_waitfunc_nand(chip); |
---|
| 364 | + lpc32xx_waitfunc_controller(chip); |
---|
376 | 365 | |
---|
377 | 366 | return NAND_STATUS_READY; |
---|
378 | 367 | } |
---|
.. | .. |
---|
442 | 431 | return -ENXIO; |
---|
443 | 432 | } |
---|
444 | 433 | |
---|
445 | | -static int lpc32xx_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
---|
446 | | - uint8_t *buf, int oob_required, int page) |
---|
| 434 | +static int lpc32xx_read_page(struct nand_chip *chip, uint8_t *buf, |
---|
| 435 | + int oob_required, int page) |
---|
447 | 436 | { |
---|
| 437 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
448 | 438 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
---|
449 | 439 | int i, j; |
---|
450 | 440 | uint8_t *oobbuf = chip->oob_poi; |
---|
.. | .. |
---|
470 | 460 | writeb(0x00, MLC_ECC_AUTO_DEC_REG(host->io_base)); |
---|
471 | 461 | |
---|
472 | 462 | /* Wait for Controller Ready */ |
---|
473 | | - lpc32xx_waitfunc_controller(mtd, chip); |
---|
| 463 | + lpc32xx_waitfunc_controller(chip); |
---|
474 | 464 | |
---|
475 | 465 | /* Check ECC Error status */ |
---|
476 | 466 | mlc_isr = readl(MLC_ISR(host->io_base)); |
---|
.. | .. |
---|
507 | 497 | return 0; |
---|
508 | 498 | } |
---|
509 | 499 | |
---|
510 | | -static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd, |
---|
511 | | - struct nand_chip *chip, |
---|
| 500 | +static int lpc32xx_write_page_lowlevel(struct nand_chip *chip, |
---|
512 | 501 | const uint8_t *buf, int oob_required, |
---|
513 | 502 | int page) |
---|
514 | 503 | { |
---|
| 504 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
515 | 505 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
---|
516 | 506 | const uint8_t *oobbuf = chip->oob_poi; |
---|
517 | 507 | uint8_t *dma_buf = (uint8_t *)buf; |
---|
.. | .. |
---|
551 | 541 | writeb(0x00, MLC_ECC_AUTO_ENC_REG(host->io_base)); |
---|
552 | 542 | |
---|
553 | 543 | /* Wait for Controller Ready */ |
---|
554 | | - lpc32xx_waitfunc_controller(mtd, chip); |
---|
| 544 | + lpc32xx_waitfunc_controller(chip); |
---|
555 | 545 | } |
---|
556 | 546 | |
---|
557 | 547 | return nand_prog_page_end_op(chip); |
---|
558 | 548 | } |
---|
559 | 549 | |
---|
560 | | -static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
---|
561 | | - int page) |
---|
| 550 | +static int lpc32xx_read_oob(struct nand_chip *chip, int page) |
---|
562 | 551 | { |
---|
563 | 552 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
---|
564 | 553 | |
---|
565 | 554 | /* Read whole page - necessary with MLC controller! */ |
---|
566 | | - lpc32xx_read_page(mtd, chip, host->dummy_buf, 1, page); |
---|
| 555 | + lpc32xx_read_page(chip, host->dummy_buf, 1, page); |
---|
567 | 556 | |
---|
568 | 557 | return 0; |
---|
569 | 558 | } |
---|
570 | 559 | |
---|
571 | | -static int lpc32xx_write_oob(struct mtd_info *mtd, struct nand_chip *chip, |
---|
572 | | - int page) |
---|
| 560 | +static int lpc32xx_write_oob(struct nand_chip *chip, int page) |
---|
573 | 561 | { |
---|
574 | 562 | /* None, write_oob conflicts with the automatic LPC MLC ECC decoder! */ |
---|
575 | 563 | return 0; |
---|
576 | 564 | } |
---|
577 | 565 | |
---|
578 | 566 | /* Prepares MLC for transfers with H/W ECC enabled: always enabled anyway */ |
---|
579 | | -static void lpc32xx_ecc_enable(struct mtd_info *mtd, int mode) |
---|
| 567 | +static void lpc32xx_ecc_enable(struct nand_chip *chip, int mode) |
---|
580 | 568 | { |
---|
581 | 569 | /* Always enabled! */ |
---|
582 | 570 | } |
---|
.. | .. |
---|
660 | 648 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
---|
661 | 649 | struct device *dev = &host->pdev->dev; |
---|
662 | 650 | |
---|
| 651 | + if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) |
---|
| 652 | + return 0; |
---|
| 653 | + |
---|
663 | 654 | host->dma_buf = devm_kzalloc(dev, mtd->writesize, GFP_KERNEL); |
---|
664 | 655 | if (!host->dma_buf) |
---|
665 | 656 | return -ENOMEM; |
---|
.. | .. |
---|
668 | 659 | if (!host->dummy_buf) |
---|
669 | 660 | return -ENOMEM; |
---|
670 | 661 | |
---|
671 | | - chip->ecc.mode = NAND_ECC_HW; |
---|
672 | 662 | chip->ecc.size = 512; |
---|
| 663 | + chip->ecc.hwctl = lpc32xx_ecc_enable; |
---|
| 664 | + chip->ecc.read_page_raw = lpc32xx_read_page; |
---|
| 665 | + chip->ecc.read_page = lpc32xx_read_page; |
---|
| 666 | + chip->ecc.write_page_raw = lpc32xx_write_page_lowlevel; |
---|
| 667 | + chip->ecc.write_page = lpc32xx_write_page_lowlevel; |
---|
| 668 | + chip->ecc.write_oob = lpc32xx_write_oob; |
---|
| 669 | + chip->ecc.read_oob = lpc32xx_read_oob; |
---|
| 670 | + chip->ecc.strength = 4; |
---|
| 671 | + chip->ecc.bytes = 10; |
---|
| 672 | + |
---|
673 | 673 | mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops); |
---|
674 | 674 | host->mlcsubpages = mtd->writesize / 512; |
---|
675 | 675 | |
---|
.. | .. |
---|
741 | 741 | if (res) |
---|
742 | 742 | goto put_clk; |
---|
743 | 743 | |
---|
744 | | - nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl; |
---|
745 | | - nand_chip->dev_ready = lpc32xx_nand_device_ready; |
---|
746 | | - nand_chip->chip_delay = 25; /* us */ |
---|
747 | | - nand_chip->IO_ADDR_R = MLC_DATA(host->io_base); |
---|
748 | | - nand_chip->IO_ADDR_W = MLC_DATA(host->io_base); |
---|
| 744 | + nand_chip->legacy.cmd_ctrl = lpc32xx_nand_cmd_ctrl; |
---|
| 745 | + nand_chip->legacy.dev_ready = lpc32xx_nand_device_ready; |
---|
| 746 | + nand_chip->legacy.chip_delay = 25; /* us */ |
---|
| 747 | + nand_chip->legacy.IO_ADDR_R = MLC_DATA(host->io_base); |
---|
| 748 | + nand_chip->legacy.IO_ADDR_W = MLC_DATA(host->io_base); |
---|
749 | 749 | |
---|
750 | 750 | /* Init NAND controller */ |
---|
751 | 751 | lpc32xx_nand_setup(host); |
---|
.. | .. |
---|
753 | 753 | platform_set_drvdata(pdev, host); |
---|
754 | 754 | |
---|
755 | 755 | /* Initialize function pointers */ |
---|
756 | | - nand_chip->ecc.hwctl = lpc32xx_ecc_enable; |
---|
757 | | - nand_chip->ecc.read_page_raw = lpc32xx_read_page; |
---|
758 | | - nand_chip->ecc.read_page = lpc32xx_read_page; |
---|
759 | | - nand_chip->ecc.write_page_raw = lpc32xx_write_page_lowlevel; |
---|
760 | | - nand_chip->ecc.write_page = lpc32xx_write_page_lowlevel; |
---|
761 | | - nand_chip->ecc.write_oob = lpc32xx_write_oob; |
---|
762 | | - nand_chip->ecc.read_oob = lpc32xx_read_oob; |
---|
763 | | - nand_chip->ecc.strength = 4; |
---|
764 | | - nand_chip->ecc.bytes = 10; |
---|
765 | | - nand_chip->waitfunc = lpc32xx_waitfunc; |
---|
| 756 | + nand_chip->legacy.waitfunc = lpc32xx_waitfunc; |
---|
766 | 757 | |
---|
767 | 758 | nand_chip->options = NAND_NO_SUBPAGE_WRITE; |
---|
768 | 759 | nand_chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; |
---|
.. | .. |
---|
785 | 776 | |
---|
786 | 777 | host->irq = platform_get_irq(pdev, 0); |
---|
787 | 778 | if (host->irq < 0) { |
---|
788 | | - dev_err(&pdev->dev, "failed to get platform irq\n"); |
---|
789 | 779 | res = -EINVAL; |
---|
790 | 780 | goto release_dma_chan; |
---|
791 | 781 | } |
---|
.. | .. |
---|
801 | 791 | * Scan to find existence of the device and get the type of NAND device: |
---|
802 | 792 | * SMALL block or LARGE block. |
---|
803 | 793 | */ |
---|
804 | | - nand_chip->dummy_controller.ops = &lpc32xx_nand_controller_ops; |
---|
| 794 | + nand_chip->legacy.dummy_controller.ops = &lpc32xx_nand_controller_ops; |
---|
805 | 795 | res = nand_scan(nand_chip, 1); |
---|
806 | 796 | if (res) |
---|
807 | 797 | goto free_irq; |
---|
.. | .. |
---|
839 | 829 | static int lpc32xx_nand_remove(struct platform_device *pdev) |
---|
840 | 830 | { |
---|
841 | 831 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); |
---|
| 832 | + struct nand_chip *chip = &host->nand_chip; |
---|
| 833 | + int ret; |
---|
842 | 834 | |
---|
843 | | - nand_release(&host->nand_chip); |
---|
| 835 | + ret = mtd_device_unregister(nand_to_mtd(chip)); |
---|
| 836 | + WARN_ON(ret); |
---|
| 837 | + nand_cleanup(chip); |
---|
| 838 | + |
---|
844 | 839 | free_irq(host->irq, host); |
---|
845 | 840 | if (use_dma) |
---|
846 | 841 | dma_release_channel(host->dma_chan); |
---|