aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand/onenand_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/onenand/onenand_base.c')
-rw-r--r--drivers/mtd/onenand/onenand_base.c54
1 files changed, 42 insertions, 12 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 56a8b2005bda..ac9e959802a7 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -65,11 +65,11 @@ MODULE_PARM_DESC(otp, "Corresponding behaviour of OneNAND in OTP"
65 " : 2 -> 1st Block lock" 65 " : 2 -> 1st Block lock"
66 " : 3 -> BOTH OTP Block and 1st Block lock"); 66 " : 3 -> BOTH OTP Block and 1st Block lock");
67 67
68/** 68/*
69 * onenand_oob_128 - oob info for Flex-Onenand with 4KB page 69 * flexonenand_oob_128 - oob info for Flex-Onenand with 4KB page
70 * For now, we expose only 64 out of 80 ecc bytes 70 * For now, we expose only 64 out of 80 ecc bytes
71 */ 71 */
72static struct nand_ecclayout onenand_oob_128 = { 72static struct nand_ecclayout flexonenand_oob_128 = {
73 .eccbytes = 64, 73 .eccbytes = 64,
74 .eccpos = { 74 .eccpos = {
75 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 75 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
@@ -86,6 +86,35 @@ static struct nand_ecclayout onenand_oob_128 = {
86 } 86 }
87}; 87};
88 88
89/*
90 * onenand_oob_128 - oob info for OneNAND with 4KB page
91 *
92 * Based on specification:
93 * 4Gb M-die OneNAND Flash (KFM4G16Q4M, KFN8G16Q4M). Rev. 1.3, Apr. 2010
94 *
95 * For eccpos we expose only 64 bytes out of 72 (see struct nand_ecclayout)
96 *
97 * oobfree uses the spare area fields marked as
98 * "Managed by internal ECC logic for Logical Sector Number area"
99 */
100static struct nand_ecclayout onenand_oob_128 = {
101 .eccbytes = 64,
102 .eccpos = {
103 7, 8, 9, 10, 11, 12, 13, 14, 15,
104 23, 24, 25, 26, 27, 28, 29, 30, 31,
105 39, 40, 41, 42, 43, 44, 45, 46, 47,
106 55, 56, 57, 58, 59, 60, 61, 62, 63,
107 71, 72, 73, 74, 75, 76, 77, 78, 79,
108 87, 88, 89, 90, 91, 92, 93, 94, 95,
109 103, 104, 105, 106, 107, 108, 109, 110, 111,
110 119
111 },
112 .oobfree = {
113 {2, 3}, {18, 3}, {34, 3}, {50, 3},
114 {66, 3}, {82, 3}, {98, 3}, {114, 3}
115 }
116};
117
89/** 118/**
90 * onenand_oob_64 - oob info for large (2KB) page 119 * onenand_oob_64 - oob info for large (2KB) page
91 */ 120 */
@@ -2424,7 +2453,7 @@ static int onenand_block_by_block_erase(struct mtd_info *mtd,
2424 len -= block_size; 2453 len -= block_size;
2425 addr += block_size; 2454 addr += block_size;
2426 2455
2427 if (addr == region_end) { 2456 if (region && addr == region_end) {
2428 if (!len) 2457 if (!len)
2429 break; 2458 break;
2430 region++; 2459 region++;
@@ -4018,8 +4047,13 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
4018 */ 4047 */
4019 switch (mtd->oobsize) { 4048 switch (mtd->oobsize) {
4020 case 128: 4049 case 128:
4021 this->ecclayout = &onenand_oob_128; 4050 if (FLEXONENAND(this)) {
4022 mtd->subpage_sft = 0; 4051 this->ecclayout = &flexonenand_oob_128;
4052 mtd->subpage_sft = 0;
4053 } else {
4054 this->ecclayout = &onenand_oob_128;
4055 mtd->subpage_sft = 2;
4056 }
4023 break; 4057 break;
4024 case 64: 4058 case 64:
4025 this->ecclayout = &onenand_oob_64; 4059 this->ecclayout = &onenand_oob_64;
@@ -4108,12 +4142,8 @@ void onenand_release(struct mtd_info *mtd)
4108{ 4142{
4109 struct onenand_chip *this = mtd->priv; 4143 struct onenand_chip *this = mtd->priv;
4110 4144
4111#ifdef CONFIG_MTD_PARTITIONS
4112 /* Deregister partitions */ 4145 /* Deregister partitions */
4113 del_mtd_partitions (mtd); 4146 mtd_device_unregister(mtd);
4114#endif
4115 /* Deregister the device */
4116 del_mtd_device (mtd);
4117 4147
4118 /* Free bad block table memory, if allocated */ 4148 /* Free bad block table memory, if allocated */
4119 if (this->bbm) { 4149 if (this->bbm) {