| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright 2009-2015 Freescale Semiconductor, Inc. and others |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 9 | 10 | * Jason Jin <Jason.jin@freescale.com> |
|---|
| 10 | 11 | * |
|---|
| 11 | 12 | * Based on original driver mpc5121_nfc.c. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This is free software; you can redistribute it and/or modify it |
|---|
| 14 | | - * under the terms of the GNU General Public License as published by |
|---|
| 15 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 16 | | - * (at your option) any later version. |
|---|
| 17 | 13 | * |
|---|
| 18 | 14 | * Limitations: |
|---|
| 19 | 15 | * - Untested on MPC5125 and M54418. |
|---|
| .. | .. |
|---|
| 152 | 148 | }; |
|---|
| 153 | 149 | |
|---|
| 154 | 150 | struct vf610_nfc { |
|---|
| 151 | + struct nand_controller base; |
|---|
| 155 | 152 | struct nand_chip chip; |
|---|
| 156 | 153 | struct device *dev; |
|---|
| 157 | 154 | void __iomem *regs; |
|---|
| .. | .. |
|---|
| 167 | 164 | bool data_access; |
|---|
| 168 | 165 | u32 ecc_mode; |
|---|
| 169 | 166 | }; |
|---|
| 170 | | - |
|---|
| 171 | | -static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info *mtd) |
|---|
| 172 | | -{ |
|---|
| 173 | | - return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip); |
|---|
| 174 | | -} |
|---|
| 175 | 167 | |
|---|
| 176 | 168 | static inline struct vf610_nfc *chip_to_nfc(struct nand_chip *chip) |
|---|
| 177 | 169 | { |
|---|
| .. | .. |
|---|
| 316 | 308 | |
|---|
| 317 | 309 | static irqreturn_t vf610_nfc_irq(int irq, void *data) |
|---|
| 318 | 310 | { |
|---|
| 319 | | - struct mtd_info *mtd = data; |
|---|
| 320 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 311 | + struct vf610_nfc *nfc = data; |
|---|
| 321 | 312 | |
|---|
| 322 | 313 | vf610_nfc_clear(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT); |
|---|
| 323 | 314 | complete(&nfc->cmd_done); |
|---|
| .. | .. |
|---|
| 330 | 321 | vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, |
|---|
| 331 | 322 | CONFIG_ECC_MODE_MASK, |
|---|
| 332 | 323 | CONFIG_ECC_MODE_SHIFT, ecc_mode); |
|---|
| 333 | | -} |
|---|
| 334 | | - |
|---|
| 335 | | -static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size) |
|---|
| 336 | | -{ |
|---|
| 337 | | - vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size); |
|---|
| 338 | 324 | } |
|---|
| 339 | 325 | |
|---|
| 340 | 326 | static inline void vf610_nfc_run(struct vf610_nfc *nfc, u32 col, u32 row, |
|---|
| .. | .. |
|---|
| 373 | 359 | { |
|---|
| 374 | 360 | const struct nand_op_instr *instr; |
|---|
| 375 | 361 | struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 376 | | - int op_id = -1, trfr_sz = 0, offset; |
|---|
| 362 | + int op_id = -1, trfr_sz = 0, offset = 0; |
|---|
| 377 | 363 | u32 col = 0, row = 0, cmd1 = 0, cmd2 = 0, code = 0; |
|---|
| 378 | 364 | bool force8bit = false; |
|---|
| 379 | 365 | |
|---|
| .. | .. |
|---|
| 487 | 473 | NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, PAGE_2K + OOB_MAX)), |
|---|
| 488 | 474 | ); |
|---|
| 489 | 475 | |
|---|
| 490 | | -static int vf610_nfc_exec_op(struct nand_chip *chip, |
|---|
| 491 | | - const struct nand_operation *op, |
|---|
| 492 | | - bool check_only) |
|---|
| 493 | | -{ |
|---|
| 494 | | - return nand_op_parser_exec_op(chip, &vf610_nfc_op_parser, op, |
|---|
| 495 | | - check_only); |
|---|
| 496 | | -} |
|---|
| 497 | | - |
|---|
| 498 | 476 | /* |
|---|
| 499 | 477 | * This function supports Vybrid only (MPC5125 would have full RB and four CS) |
|---|
| 500 | 478 | */ |
|---|
| 501 | | -static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip) |
|---|
| 479 | +static void vf610_nfc_select_target(struct nand_chip *chip, unsigned int cs) |
|---|
| 502 | 480 | { |
|---|
| 503 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 504 | | - u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR); |
|---|
| 481 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 482 | + u32 tmp; |
|---|
| 505 | 483 | |
|---|
| 506 | 484 | /* Vybrid only (MPC5125 would have full RB and four CS) */ |
|---|
| 507 | 485 | if (nfc->variant != NFC_VFC610) |
|---|
| 508 | 486 | return; |
|---|
| 509 | 487 | |
|---|
| 488 | + tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR); |
|---|
| 510 | 489 | tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK); |
|---|
| 511 | | - |
|---|
| 512 | | - if (chip >= 0) { |
|---|
| 513 | | - tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT; |
|---|
| 514 | | - tmp |= BIT(chip) << ROW_ADDR_CHIP_SEL_SHIFT; |
|---|
| 515 | | - } |
|---|
| 490 | + tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT; |
|---|
| 491 | + tmp |= BIT(cs) << ROW_ADDR_CHIP_SEL_SHIFT; |
|---|
| 516 | 492 | |
|---|
| 517 | 493 | vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp); |
|---|
| 518 | 494 | } |
|---|
| 519 | 495 | |
|---|
| 520 | | -static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat, |
|---|
| 496 | +static int vf610_nfc_exec_op(struct nand_chip *chip, |
|---|
| 497 | + const struct nand_operation *op, |
|---|
| 498 | + bool check_only) |
|---|
| 499 | +{ |
|---|
| 500 | + if (!check_only) |
|---|
| 501 | + vf610_nfc_select_target(chip, op->cs); |
|---|
| 502 | + |
|---|
| 503 | + return nand_op_parser_exec_op(chip, &vf610_nfc_op_parser, op, |
|---|
| 504 | + check_only); |
|---|
| 505 | +} |
|---|
| 506 | + |
|---|
| 507 | +static inline int vf610_nfc_correct_data(struct nand_chip *chip, uint8_t *dat, |
|---|
| 521 | 508 | uint8_t *oob, int page) |
|---|
| 522 | 509 | { |
|---|
| 523 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 510 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 511 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 524 | 512 | u32 ecc_status_off = NFC_MAIN_AREA(0) + ECC_SRAM_ADDR + ECC_STATUS; |
|---|
| 525 | 513 | u8 ecc_status; |
|---|
| 526 | 514 | u8 ecc_count; |
|---|
| .. | .. |
|---|
| 557 | 545 | } |
|---|
| 558 | 546 | } |
|---|
| 559 | 547 | |
|---|
| 560 | | -static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
|---|
| 561 | | - uint8_t *buf, int oob_required, int page) |
|---|
| 548 | +static int vf610_nfc_read_page(struct nand_chip *chip, uint8_t *buf, |
|---|
| 549 | + int oob_required, int page) |
|---|
| 562 | 550 | { |
|---|
| 563 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 551 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 552 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 564 | 553 | int trfr_sz = mtd->writesize + mtd->oobsize; |
|---|
| 565 | 554 | u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0; |
|---|
| 566 | 555 | int stat; |
|---|
| 556 | + |
|---|
| 557 | + vf610_nfc_select_target(chip, chip->cur_cs); |
|---|
| 567 | 558 | |
|---|
| 568 | 559 | cmd2 |= NAND_CMD_READ0 << CMD_BYTE1_SHIFT; |
|---|
| 569 | 560 | code |= COMMAND_CMD_BYTE1 | COMMAND_CAR_BYTE1 | COMMAND_CAR_BYTE2; |
|---|
| .. | .. |
|---|
| 591 | 582 | mtd->writesize, |
|---|
| 592 | 583 | mtd->oobsize, false); |
|---|
| 593 | 584 | |
|---|
| 594 | | - stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, page); |
|---|
| 585 | + stat = vf610_nfc_correct_data(chip, buf, chip->oob_poi, page); |
|---|
| 595 | 586 | |
|---|
| 596 | 587 | if (stat < 0) { |
|---|
| 597 | 588 | mtd->ecc_stats.failed++; |
|---|
| .. | .. |
|---|
| 602 | 593 | } |
|---|
| 603 | 594 | } |
|---|
| 604 | 595 | |
|---|
| 605 | | -static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
|---|
| 606 | | - const uint8_t *buf, int oob_required, int page) |
|---|
| 596 | +static int vf610_nfc_write_page(struct nand_chip *chip, const uint8_t *buf, |
|---|
| 597 | + int oob_required, int page) |
|---|
| 607 | 598 | { |
|---|
| 608 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 599 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 600 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 609 | 601 | int trfr_sz = mtd->writesize + mtd->oobsize; |
|---|
| 610 | 602 | u32 row = 0, cmd1 = 0, cmd2 = 0, code = 0; |
|---|
| 611 | 603 | u8 status; |
|---|
| 612 | 604 | int ret; |
|---|
| 605 | + |
|---|
| 606 | + vf610_nfc_select_target(chip, chip->cur_cs); |
|---|
| 613 | 607 | |
|---|
| 614 | 608 | cmd2 |= NAND_CMD_SEQIN << CMD_BYTE1_SHIFT; |
|---|
| 615 | 609 | code |= COMMAND_CMD_BYTE1 | COMMAND_CAR_BYTE1 | COMMAND_CAR_BYTE2; |
|---|
| .. | .. |
|---|
| 643 | 637 | return 0; |
|---|
| 644 | 638 | } |
|---|
| 645 | 639 | |
|---|
| 646 | | -static int vf610_nfc_read_page_raw(struct mtd_info *mtd, |
|---|
| 647 | | - struct nand_chip *chip, u8 *buf, |
|---|
| 640 | +static int vf610_nfc_read_page_raw(struct nand_chip *chip, u8 *buf, |
|---|
| 648 | 641 | int oob_required, int page) |
|---|
| 649 | 642 | { |
|---|
| 650 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 643 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 651 | 644 | int ret; |
|---|
| 652 | 645 | |
|---|
| 653 | 646 | nfc->data_access = true; |
|---|
| 654 | | - ret = nand_read_page_raw(mtd, chip, buf, oob_required, page); |
|---|
| 647 | + ret = nand_read_page_raw(chip, buf, oob_required, page); |
|---|
| 655 | 648 | nfc->data_access = false; |
|---|
| 656 | 649 | |
|---|
| 657 | 650 | return ret; |
|---|
| 658 | 651 | } |
|---|
| 659 | 652 | |
|---|
| 660 | | -static int vf610_nfc_write_page_raw(struct mtd_info *mtd, |
|---|
| 661 | | - struct nand_chip *chip, const u8 *buf, |
|---|
| 653 | +static int vf610_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, |
|---|
| 662 | 654 | int oob_required, int page) |
|---|
| 663 | 655 | { |
|---|
| 664 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 656 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 657 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 665 | 658 | int ret; |
|---|
| 666 | 659 | |
|---|
| 667 | 660 | nfc->data_access = true; |
|---|
| .. | .. |
|---|
| 677 | 670 | return nand_prog_page_end_op(chip); |
|---|
| 678 | 671 | } |
|---|
| 679 | 672 | |
|---|
| 680 | | -static int vf610_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
|---|
| 681 | | - int page) |
|---|
| 673 | +static int vf610_nfc_read_oob(struct nand_chip *chip, int page) |
|---|
| 682 | 674 | { |
|---|
| 683 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 675 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 684 | 676 | int ret; |
|---|
| 685 | 677 | |
|---|
| 686 | 678 | nfc->data_access = true; |
|---|
| 687 | | - ret = nand_read_oob_std(mtd, chip, page); |
|---|
| 679 | + ret = nand_read_oob_std(chip, page); |
|---|
| 688 | 680 | nfc->data_access = false; |
|---|
| 689 | 681 | |
|---|
| 690 | 682 | return ret; |
|---|
| 691 | 683 | } |
|---|
| 692 | 684 | |
|---|
| 693 | | -static int vf610_nfc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, |
|---|
| 694 | | - int page) |
|---|
| 685 | +static int vf610_nfc_write_oob(struct nand_chip *chip, int page) |
|---|
| 695 | 686 | { |
|---|
| 696 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 687 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 688 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 697 | 689 | int ret; |
|---|
| 698 | 690 | |
|---|
| 699 | 691 | nfc->data_access = true; |
|---|
| .. | .. |
|---|
| 735 | 727 | else |
|---|
| 736 | 728 | vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT); |
|---|
| 737 | 729 | |
|---|
| 738 | | - if (nfc->chip.ecc.mode == NAND_ECC_HW) { |
|---|
| 730 | + if (nfc->chip.ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) { |
|---|
| 739 | 731 | /* Set ECC status offset in SRAM */ |
|---|
| 740 | 732 | vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, |
|---|
| 741 | 733 | CONFIG_ECC_SRAM_ADDR_MASK, |
|---|
| .. | .. |
|---|
| 750 | 742 | static int vf610_nfc_attach_chip(struct nand_chip *chip) |
|---|
| 751 | 743 | { |
|---|
| 752 | 744 | struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 753 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 745 | + struct vf610_nfc *nfc = chip_to_nfc(chip); |
|---|
| 754 | 746 | |
|---|
| 755 | 747 | vf610_nfc_init_controller(nfc); |
|---|
| 756 | 748 | |
|---|
| .. | .. |
|---|
| 764 | 756 | return -ENXIO; |
|---|
| 765 | 757 | } |
|---|
| 766 | 758 | |
|---|
| 767 | | - if (chip->ecc.mode != NAND_ECC_HW) |
|---|
| 759 | + if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) |
|---|
| 768 | 760 | return 0; |
|---|
| 769 | 761 | |
|---|
| 770 | 762 | if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) { |
|---|
| .. | .. |
|---|
| 782 | 774 | mtd->oobsize = 64; |
|---|
| 783 | 775 | |
|---|
| 784 | 776 | /* Use default large page ECC layout defined in NAND core */ |
|---|
| 785 | | - mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); |
|---|
| 777 | + mtd_set_ooblayout(mtd, nand_get_large_page_ooblayout()); |
|---|
| 786 | 778 | if (chip->ecc.strength == 32) { |
|---|
| 787 | 779 | nfc->ecc_mode = ECC_60_BYTE; |
|---|
| 788 | 780 | chip->ecc.bytes = 60; |
|---|
| .. | .. |
|---|
| 808 | 800 | |
|---|
| 809 | 801 | static const struct nand_controller_ops vf610_nfc_controller_ops = { |
|---|
| 810 | 802 | .attach_chip = vf610_nfc_attach_chip, |
|---|
| 803 | + .exec_op = vf610_nfc_exec_op, |
|---|
| 804 | + |
|---|
| 811 | 805 | }; |
|---|
| 812 | 806 | |
|---|
| 813 | 807 | static int vf610_nfc_probe(struct platform_device *pdev) |
|---|
| .. | .. |
|---|
| 853 | 847 | } |
|---|
| 854 | 848 | |
|---|
| 855 | 849 | of_id = of_match_device(vf610_nfc_dt_ids, &pdev->dev); |
|---|
| 850 | + if (!of_id) { |
|---|
| 851 | + err = -ENODEV; |
|---|
| 852 | + goto err_disable_clk; |
|---|
| 853 | + } |
|---|
| 854 | + |
|---|
| 856 | 855 | nfc->variant = (enum vf610_nfc_variant)of_id->data; |
|---|
| 857 | 856 | |
|---|
| 858 | 857 | for_each_available_child_of_node(nfc->dev->of_node, child) { |
|---|
| .. | .. |
|---|
| 862 | 861 | dev_err(nfc->dev, |
|---|
| 863 | 862 | "Only one NAND chip supported!\n"); |
|---|
| 864 | 863 | err = -EINVAL; |
|---|
| 864 | + of_node_put(child); |
|---|
| 865 | 865 | goto err_disable_clk; |
|---|
| 866 | 866 | } |
|---|
| 867 | 867 | |
|---|
| .. | .. |
|---|
| 875 | 875 | goto err_disable_clk; |
|---|
| 876 | 876 | } |
|---|
| 877 | 877 | |
|---|
| 878 | | - chip->exec_op = vf610_nfc_exec_op; |
|---|
| 879 | | - chip->select_chip = vf610_nfc_select_chip; |
|---|
| 880 | | - |
|---|
| 881 | 878 | chip->options |= NAND_NO_SUBPAGE_WRITE; |
|---|
| 882 | 879 | |
|---|
| 883 | 880 | init_completion(&nfc->cmd_done); |
|---|
| 884 | 881 | |
|---|
| 885 | | - err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd); |
|---|
| 882 | + err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, nfc); |
|---|
| 886 | 883 | if (err) { |
|---|
| 887 | 884 | dev_err(nfc->dev, "Error requesting IRQ!\n"); |
|---|
| 888 | 885 | goto err_disable_clk; |
|---|
| .. | .. |
|---|
| 890 | 887 | |
|---|
| 891 | 888 | vf610_nfc_preinit_controller(nfc); |
|---|
| 892 | 889 | |
|---|
| 890 | + nand_controller_init(&nfc->base); |
|---|
| 891 | + nfc->base.ops = &vf610_nfc_controller_ops; |
|---|
| 892 | + chip->controller = &nfc->base; |
|---|
| 893 | + |
|---|
| 893 | 894 | /* Scan the NAND chip */ |
|---|
| 894 | | - chip->dummy_controller.ops = &vf610_nfc_controller_ops; |
|---|
| 895 | 895 | err = nand_scan(chip, 1); |
|---|
| 896 | 896 | if (err) |
|---|
| 897 | 897 | goto err_disable_clk; |
|---|
| 898 | 898 | |
|---|
| 899 | | - platform_set_drvdata(pdev, mtd); |
|---|
| 899 | + platform_set_drvdata(pdev, nfc); |
|---|
| 900 | 900 | |
|---|
| 901 | 901 | /* Register device in MTD */ |
|---|
| 902 | 902 | err = mtd_device_register(mtd, NULL, 0); |
|---|
| .. | .. |
|---|
| 913 | 913 | |
|---|
| 914 | 914 | static int vf610_nfc_remove(struct platform_device *pdev) |
|---|
| 915 | 915 | { |
|---|
| 916 | | - struct mtd_info *mtd = platform_get_drvdata(pdev); |
|---|
| 917 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 916 | + struct vf610_nfc *nfc = platform_get_drvdata(pdev); |
|---|
| 917 | + struct nand_chip *chip = &nfc->chip; |
|---|
| 918 | + int ret; |
|---|
| 918 | 919 | |
|---|
| 919 | | - nand_release(mtd_to_nand(mtd)); |
|---|
| 920 | + ret = mtd_device_unregister(nand_to_mtd(chip)); |
|---|
| 921 | + WARN_ON(ret); |
|---|
| 922 | + nand_cleanup(chip); |
|---|
| 920 | 923 | clk_disable_unprepare(nfc->clk); |
|---|
| 921 | 924 | return 0; |
|---|
| 922 | 925 | } |
|---|
| .. | .. |
|---|
| 924 | 927 | #ifdef CONFIG_PM_SLEEP |
|---|
| 925 | 928 | static int vf610_nfc_suspend(struct device *dev) |
|---|
| 926 | 929 | { |
|---|
| 927 | | - struct mtd_info *mtd = dev_get_drvdata(dev); |
|---|
| 928 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 930 | + struct vf610_nfc *nfc = dev_get_drvdata(dev); |
|---|
| 929 | 931 | |
|---|
| 930 | 932 | clk_disable_unprepare(nfc->clk); |
|---|
| 931 | 933 | return 0; |
|---|
| .. | .. |
|---|
| 933 | 935 | |
|---|
| 934 | 936 | static int vf610_nfc_resume(struct device *dev) |
|---|
| 935 | 937 | { |
|---|
| 938 | + struct vf610_nfc *nfc = dev_get_drvdata(dev); |
|---|
| 936 | 939 | int err; |
|---|
| 937 | | - |
|---|
| 938 | | - struct mtd_info *mtd = dev_get_drvdata(dev); |
|---|
| 939 | | - struct vf610_nfc *nfc = mtd_to_nfc(mtd); |
|---|
| 940 | 940 | |
|---|
| 941 | 941 | err = clk_prepare_enable(nfc->clk); |
|---|
| 942 | 942 | if (err) |
|---|