Skip to content

Commit ee1b834

Browse files
author
Jon Lin
committed
drivers: rkflash: Change to use the api which the oob area available
Fixes: 3eb8920 ("drivers: rkflash: Support spinand non aligned read") Change-Id: I3146cd574ac77c2d1a0b5b6563440d86766a0a9a Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
1 parent eea24fe commit ee1b834

5 files changed

Lines changed: 69 additions & 22 deletions

File tree

drivers/rkflash/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
obj-$(CONFIG_RK_NANDC_NAND) += rkflash_blk.o rkflash_debug.o rksftl.o rknandc_base.o nand_boot.o flash.o nandc.o
44
obj-$(CONFIG_RK_SFC_NAND) += rkflash_blk.o rkflash_debug.o rksftl.o rksfc_base.o sfc_nand_boot.o sfc_nand.o sfc.o
5-
obj-$(CONFIG_RK_SFC_NAND_MTD) += sfc_nand_mtd.o
5+
obj-$(CONFIG_RK_SFC_NAND_MTD) += sfc_nand_mtd.o sfc_nand_mtd_bbt.o
66
obj-$(CONFIG_RK_SFC_NOR) += rkflash_blk.o rkflash_debug.o rksfc_base.o sfc_nor_boot.o sfc_nor.o sfc.o
77
obj-$(CONFIG_RK_SFC_NOR_MTD) += sfc_nor_mtd.o
88

drivers/rkflash/sfc_nand.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ u32 sfc_nand_read_page_raw(u8 cs, u32 addr, u32 *p_page_buf)
697697
{
698698
u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page;
699699

700-
return sfc_nand_read(addr, gp_page_buf, 0, page_size);
700+
return sfc_nand_read(addr, p_page_buf, 0, page_size);
701701
}
702702

703703
u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare)

drivers/rkflash/sfc_nand_mtd.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111

1212
#include "rkflash_blk.h"
1313
#include "rkflash_debug.h"
14+
#include "sfc_nand.h"
1415
#include "sfc_nand_mtd.h"
1516

17+
#ifdef CONFIG_RK_SFC_NAND_MTD
18+
1619
static struct mtd_partition nand_parts[MAX_PART_COUNT];
1720

1821
static inline struct snand_mtd_dev *mtd_to_priv(struct mtd_info *ptr_mtd)
@@ -21,7 +24,7 @@ static inline struct snand_mtd_dev *mtd_to_priv(struct mtd_info *ptr_mtd)
2124
offsetof(struct snand_mtd_dev, mtd));
2225
}
2326

24-
static int sfc_nand_erase_mtd(struct mtd_info *mtd, u32 addr)
27+
int sfc_nand_erase_mtd(struct mtd_info *mtd, u32 addr)
2528
{
2629
return sfc_nand_erase_block(0, addr >> mtd->writesize_shift);
2730
}
@@ -118,7 +121,7 @@ static int sfc_nand_read_mtd(struct mtd_info *mtd, loff_t from,
118121
return ret ? ret : max_bitflips;
119122
}
120123

121-
static int sfc_nand_isbad_mtd(struct mtd_info *mtd, loff_t ofs)
124+
int sfc_nand_isbad_mtd(struct mtd_info *mtd, loff_t ofs)
122125
{
123126
int ret;
124127
struct snand_mtd_dev *p_dev = mtd_to_priv(mtd);
@@ -205,8 +208,6 @@ static int sfc_nand_markbad_mtd(struct mtd_info *mtd, loff_t ofs)
205208
return ret;
206209
}
207210

208-
#include "sfc_nand_mtd_bbt.c"
209-
210211
static int sfc_erase_mtd(struct mtd_info *mtd, struct erase_info *instr)
211212
{
212213
struct snand_mtd_dev *p_dev = mtd_to_priv(mtd);
@@ -405,3 +406,5 @@ int sfc_nand_mtd_init(struct SFNAND_DEV *p_dev, struct mutex *lock)
405406

406407
return ret;
407408
}
409+
410+
#endif

drivers/rkflash/sfc_nand_mtd.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,15 @@ static inline struct snand_mtd_dev *mtd_to_snanddev(struct mtd_info *mtd)
6868
return mtd->priv;
6969
}
7070

71+
int snanddev_bbt_init(struct snand_mtd_dev *nand);
72+
void snanddev_bbt_cleanup(struct snand_mtd_dev *nand);
7173
int snanddev_bbt_update(struct snand_mtd_dev *nand);
7274
int snanddev_bbt_get_block_status(const struct snand_mtd_dev *nand,
7375
unsigned int entry);
7476
int snanddev_bbt_set_block_status(struct snand_mtd_dev *nand, unsigned int entry,
7577
enum nand_bbt_block_status status);
78+
79+
int sfc_nand_isbad_mtd(struct mtd_info *mtd, loff_t ofs);
80+
int sfc_nand_erase_mtd(struct mtd_info *mtd, u32 addr);
81+
7682
#endif

drivers/rkflash/sfc_nand_mtd_bbt.c

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
* Peter Pan <peterpandong@micron.com>
88
*/
99

10+
#include <linux/mtd/mtd.h>
1011
#include <linux/slab.h>
1112

13+
#include "sfc_nand.h"
1214
#include "sfc_nand_mtd.h"
1315

1416
#ifdef CONFIG_MTD_NAND_BBT_USING_FLASH
@@ -44,12 +46,13 @@ static int nanddev_read_bbt(struct snand_mtd_dev *nand, u32 block, bool update)
4446
unsigned int nbytes = DIV_ROUND_UP(nblocks * bits_per_block,
4547
BITS_PER_LONG) * sizeof(*nand->bbt.cache);
4648
struct mtd_info *mtd = snanddev_to_mtd(nand);
47-
u8 *data_buf, *oob_buf;
49+
u8 *data_buf, *oob_buf, *temp_buf;
4850
struct nanddev_bbt_info *bbt_info;
4951
struct mtd_oob_ops ops;
50-
int bbt_page_num;
52+
u32 bbt_page_num;
5153
int ret = 0;
5254
unsigned int version = 0;
55+
u32 page_addr, i;
5356

5457
if (!nand->bbt.cache)
5558
return -ENOMEM;
@@ -74,22 +77,35 @@ static int nanddev_read_bbt(struct snand_mtd_dev *nand, u32 block, bool update)
7477
bbt_info = (struct nanddev_bbt_info *)(data_buf + nbytes);
7578

7679
memset(&ops, 0, sizeof(struct mtd_oob_ops));
77-
ops.mode = MTD_OPS_RAW;
80+
ops.mode = MTD_OPS_PLACE_OOB;
7881
ops.datbuf = data_buf;
7982
ops.len = bbt_page_num * mtd->writesize;
8083
ops.oobbuf = oob_buf;
8184
ops.ooblen = bbt_page_num * mtd->oobsize;
8285
ops.ooboffs = 0;
8386

8487
/* Store one entry for each block */
85-
ret = sfc_nand_read_mtd(mtd, block * mtd->erasesize, &ops);
86-
if (ret < 0) {
87-
pr_err("%s fail %d\n", __func__, ret);
88-
ret = -EIO;
89-
goto out;
90-
} else {
91-
ret = 0;
88+
temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
89+
if (!temp_buf) {
90+
kfree(data_buf);
91+
kfree(oob_buf);
92+
93+
return -ENOMEM;
9294
}
95+
page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
96+
for (i = 0; i < bbt_page_num; i++) {
97+
ret = sfc_nand_read_page_raw(0, page_addr + i, (u32 *)temp_buf);
98+
if (ret < 0) {
99+
pr_err("%s fail %d\n", __func__, ret);
100+
ret = -EIO;
101+
kfree(temp_buf);
102+
goto out;
103+
}
104+
105+
memcpy(ops.datbuf + i * mtd->writesize, temp_buf, mtd->writesize);
106+
memcpy(ops.oobbuf + i * mtd->oobsize, temp_buf + mtd->writesize, mtd->oobsize);
107+
}
108+
kfree(temp_buf);
93109

94110
if (oob_buf[0] != 0xff && !memcmp(bbt_pattern, bbt_info->pattern, 4))
95111
version = bbt_info->version;
@@ -114,11 +130,12 @@ static int nanddev_write_bbt(struct snand_mtd_dev *nand, u32 block)
114130
unsigned int nbytes = DIV_ROUND_UP(nblocks * bits_per_block,
115131
BITS_PER_LONG) * sizeof(*nand->bbt.cache);
116132
struct mtd_info *mtd = snanddev_to_mtd(nand);
117-
u8 *data_buf, *oob_buf;
133+
u8 *data_buf, *oob_buf, *temp_buf;
118134
struct nanddev_bbt_info *bbt_info;
119135
struct mtd_oob_ops ops;
120-
int bbt_page_num;
136+
u32 bbt_page_num;
121137
int ret = 0;
138+
u32 page_addr, i;
122139

123140
BBT_DBG("write_bbt to blk=%d ver=%d\n", block, nand->bbt.version);
124141
if (!nand->bbt.cache)
@@ -149,7 +166,7 @@ static int nanddev_write_bbt(struct snand_mtd_dev *nand, u32 block)
149166
bbt_info->version = nand->bbt.version;
150167

151168
/* Store one entry for each block */
152-
ret = sfc_nand_erase_mtd(mtd, block << mtd->erasesize_shift);
169+
ret = sfc_nand_erase_mtd(mtd, block / mtd->erasesize);
153170
if (ret)
154171
goto out;
155172

@@ -159,7 +176,28 @@ static int nanddev_write_bbt(struct snand_mtd_dev *nand, u32 block)
159176
ops.oobbuf = oob_buf;
160177
ops.ooblen = bbt_page_num * mtd->oobsize;
161178
ops.ooboffs = 0;
162-
ret = sfc_nand_write_mtd(mtd, block * mtd->erasesize, &ops);
179+
180+
temp_buf = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
181+
if (!temp_buf) {
182+
kfree(data_buf);
183+
kfree(oob_buf);
184+
185+
return -ENOMEM;
186+
}
187+
page_addr = (u32)(block << (mtd->erasesize_shift - mtd->writesize_shift));
188+
for (i = 0; i < bbt_page_num; i++) {
189+
memcpy(temp_buf, ops.datbuf + i * mtd->writesize, mtd->writesize);
190+
memcpy(temp_buf + mtd->writesize, ops.oobbuf + i * mtd->oobsize, mtd->oobsize);
191+
192+
ret = sfc_nand_prog_page_raw(0, page_addr + i, (u32 *)temp_buf);
193+
if (ret < 0) {
194+
pr_err("%s fail %d\n", __func__, ret);
195+
ret = -EIO;
196+
kfree(temp_buf);
197+
goto out;
198+
}
199+
}
200+
kfree(temp_buf);
163201

164202
out:
165203
kfree(data_buf);
@@ -196,7 +234,7 @@ static int nanddev_scan_bbt(struct snand_mtd_dev *nand)
196234
{
197235
unsigned int nblocks = snanddev_neraseblocks(nand);
198236
u32 start_block, block;
199-
int ret;
237+
int ret = 0;
200238

201239
nand->bbt.version = 0;
202240
start_block = nblocks - NANDDEV_BBT_SCAN_MAXBLOCKS;
@@ -213,7 +251,7 @@ static int nanddev_scan_bbt(struct snand_mtd_dev *nand)
213251
}
214252
}
215253

216-
return 0;
254+
return ret;
217255
}
218256

219257
#endif

0 commit comments

Comments
 (0)