.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright © 2005-2009 Samsung Electronics |
---|
3 | 4 | * Copyright © 2007 Nokia Corporation |
---|
.. | .. |
---|
12 | 13 | * Flex-OneNAND support |
---|
13 | 14 | * Amul Kumar Saha <amul.saha at samsung.com> |
---|
14 | 15 | * OTP support |
---|
15 | | - * |
---|
16 | | - * This program is free software; you can redistribute it and/or modify |
---|
17 | | - * it under the terms of the GNU General Public License version 2 as |
---|
18 | | - * published by the Free Software Foundation. |
---|
19 | 16 | */ |
---|
20 | 17 | |
---|
21 | 18 | #include <linux/kernel.h> |
---|
.. | .. |
---|
1055 | 1052 | int thislen) |
---|
1056 | 1053 | { |
---|
1057 | 1054 | struct onenand_chip *this = mtd->priv; |
---|
1058 | | - int ret; |
---|
1059 | 1055 | |
---|
1060 | 1056 | this->read_bufferram(mtd, ONENAND_SPARERAM, this->oob_buf, 0, |
---|
1061 | 1057 | mtd->oobsize); |
---|
1062 | | - ret = mtd_ooblayout_get_databytes(mtd, buf, this->oob_buf, |
---|
1063 | | - column, thislen); |
---|
1064 | | - if (ret) |
---|
1065 | | - return ret; |
---|
1066 | | - |
---|
1067 | | - return 0; |
---|
| 1058 | + return mtd_ooblayout_get_databytes(mtd, buf, this->oob_buf, |
---|
| 1059 | + column, thislen); |
---|
1068 | 1060 | } |
---|
1069 | 1061 | |
---|
1070 | 1062 | /** |
---|
.. | .. |
---|
2458 | 2450 | bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); |
---|
2459 | 2451 | |
---|
2460 | 2452 | /* We write two bytes, so we don't have to mess with 16-bit access */ |
---|
2461 | | - ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); |
---|
| 2453 | + ofs += mtd->oobsize + (this->badblockpos & ~0x01); |
---|
2462 | 2454 | /* FIXME : What to do when marking SLC block in partition |
---|
2463 | 2455 | * with MLC erasesize? For now, it is not advisable to |
---|
2464 | 2456 | * create partitions containing both SLC and MLC regions. |
---|
.. | .. |
---|
2856 | 2848 | |
---|
2857 | 2849 | /* Exit OTP access mode */ |
---|
2858 | 2850 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
---|
2859 | | - this->wait(mtd, FL_RESETING); |
---|
| 2851 | + this->wait(mtd, FL_RESETTING); |
---|
2860 | 2852 | |
---|
2861 | 2853 | status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); |
---|
2862 | 2854 | status &= 0x60; |
---|
.. | .. |
---|
2927 | 2919 | |
---|
2928 | 2920 | /* Exit OTP access mode */ |
---|
2929 | 2921 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
---|
2930 | | - this->wait(mtd, FL_RESETING); |
---|
| 2922 | + this->wait(mtd, FL_RESETTING); |
---|
2931 | 2923 | |
---|
2932 | 2924 | return ret; |
---|
2933 | 2925 | } |
---|
.. | .. |
---|
2971 | 2963 | |
---|
2972 | 2964 | /* Exit OTP access mode */ |
---|
2973 | 2965 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
---|
2974 | | - this->wait(mtd, FL_RESETING); |
---|
| 2966 | + this->wait(mtd, FL_RESETTING); |
---|
2975 | 2967 | |
---|
2976 | 2968 | return ret; |
---|
2977 | 2969 | } |
---|
.. | .. |
---|
3011 | 3003 | |
---|
3012 | 3004 | /* Exit OTP access mode */ |
---|
3013 | 3005 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
---|
3014 | | - this->wait(mtd, FL_RESETING); |
---|
| 3006 | + this->wait(mtd, FL_RESETTING); |
---|
3015 | 3007 | } else { |
---|
3016 | 3008 | ops.mode = MTD_OPS_PLACE_OOB; |
---|
3017 | 3009 | ops.ooblen = len; |
---|
.. | .. |
---|
3260 | 3252 | |
---|
3261 | 3253 | /* Lock scheme */ |
---|
3262 | 3254 | switch (density) { |
---|
| 3255 | + case ONENAND_DEVICE_DENSITY_8Gb: |
---|
| 3256 | + this->options |= ONENAND_HAS_NOP_1; |
---|
| 3257 | + fallthrough; |
---|
3263 | 3258 | case ONENAND_DEVICE_DENSITY_4Gb: |
---|
3264 | 3259 | if (ONENAND_IS_DDP(this)) |
---|
3265 | 3260 | this->options |= ONENAND_HAS_2PLANE; |
---|
.. | .. |
---|
3280 | 3275 | if ((this->version_id & 0xf) == 0xe) |
---|
3281 | 3276 | this->options |= ONENAND_HAS_NOP_1; |
---|
3282 | 3277 | } |
---|
| 3278 | + this->options |= ONENAND_HAS_UNLOCK_ALL; |
---|
| 3279 | + break; |
---|
3283 | 3280 | |
---|
3284 | 3281 | case ONENAND_DEVICE_DENSITY_2Gb: |
---|
3285 | 3282 | /* 2Gb DDP does not have 2 plane */ |
---|
3286 | 3283 | if (!ONENAND_IS_DDP(this)) |
---|
3287 | 3284 | this->options |= ONENAND_HAS_2PLANE; |
---|
3288 | 3285 | this->options |= ONENAND_HAS_UNLOCK_ALL; |
---|
| 3286 | + break; |
---|
3289 | 3287 | |
---|
3290 | 3288 | case ONENAND_DEVICE_DENSITY_1Gb: |
---|
3291 | 3289 | /* A-Die has all block unlock */ |
---|
.. | .. |
---|
3410 | 3408 | this->boundary[die] = bdry & FLEXONENAND_PI_MASK; |
---|
3411 | 3409 | |
---|
3412 | 3410 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); |
---|
3413 | | - this->wait(mtd, FL_RESETING); |
---|
| 3411 | + this->wait(mtd, FL_RESETTING); |
---|
3414 | 3412 | |
---|
3415 | 3413 | printk(KERN_INFO "Die %d boundary: %d%s\n", die, |
---|
3416 | 3414 | this->boundary[die], locked ? "(Locked)" : "(Unlocked)"); |
---|
.. | .. |
---|
3632 | 3630 | ret = this->wait(mtd, FL_WRITING); |
---|
3633 | 3631 | out: |
---|
3634 | 3632 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND); |
---|
3635 | | - this->wait(mtd, FL_RESETING); |
---|
| 3633 | + this->wait(mtd, FL_RESETTING); |
---|
3636 | 3634 | if (!ret) |
---|
3637 | 3635 | /* Recalculate device size on boundary change*/ |
---|
3638 | 3636 | flexonenand_get_size(mtd); |
---|
.. | .. |
---|
3668 | 3666 | /* Reset OneNAND to read default register values */ |
---|
3669 | 3667 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM); |
---|
3670 | 3668 | /* Wait reset */ |
---|
3671 | | - this->wait(mtd, FL_RESETING); |
---|
| 3669 | + this->wait(mtd, FL_RESETTING); |
---|
3672 | 3670 | |
---|
3673 | 3671 | /* Restore system configuration 1 */ |
---|
3674 | 3672 | this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1); |
---|
.. | .. |
---|
3877 | 3875 | if (!this->oob_buf) { |
---|
3878 | 3876 | if (this->options & ONENAND_PAGEBUF_ALLOC) { |
---|
3879 | 3877 | this->options &= ~ONENAND_PAGEBUF_ALLOC; |
---|
| 3878 | +#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE |
---|
| 3879 | + kfree(this->verify_buf); |
---|
| 3880 | +#endif |
---|
3880 | 3881 | kfree(this->page_buf); |
---|
3881 | 3882 | } |
---|
3882 | 3883 | return -ENOMEM; |
---|
.. | .. |
---|
3967 | 3968 | if (!(this->options & ONENAND_SKIP_INITIAL_UNLOCKING)) |
---|
3968 | 3969 | this->unlock_all(mtd); |
---|
3969 | 3970 | |
---|
| 3971 | + /* Set the bad block marker position */ |
---|
| 3972 | + this->badblockpos = ONENAND_BADBLOCK_POS; |
---|
| 3973 | + |
---|
3970 | 3974 | ret = this->scan_bbt(mtd); |
---|
3971 | 3975 | if ((!FLEXONENAND(this)) || ret) |
---|
3972 | 3976 | return ret; |
---|