aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/linux/generic/files/drivers/mtd/nand/mtk_bmt.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/target/linux/generic/files/drivers/mtd/nand/mtk_bmt.c b/target/linux/generic/files/drivers/mtd/nand/mtk_bmt.c
index cb74b4d10f..14fbd246d7 100644
--- a/target/linux/generic/files/drivers/mtd/nand/mtk_bmt.c
+++ b/target/linux/generic/files/drivers/mtd/nand/mtk_bmt.c
@@ -90,6 +90,9 @@ static struct bmt_desc {
/* How many pages needs to store 'struct bbbt' */
u32 bmt_pgs;
+ const __be32 *remap_range;
+ int remap_range_len;
+
/* to compensate for driver level remapping */
u8 oob_offset;
} bmtd = {0};
@@ -458,17 +461,32 @@ static bool update_bmt(u16 block, int copy_len)
return true;
}
+static bool
+mapping_block_in_range(int block)
+{
+ const __be32 *cur = bmtd.remap_range;
+ u32 addr = block << bmtd.blk_shift;
+ int i;
+
+ if (!cur || !bmtd.remap_range_len)
+ return true;
+
+ for (i = 0; i < bmtd.remap_range_len; i++, cur += 2)
+ if (addr >= be32_to_cpu(cur[0]) && addr < be32_to_cpu(cur[1]))
+ return true;
+
+ return false;
+}
+
u16 get_mapping_block_index(int block)
{
- int mapping_block;
+ if (block >= bmtd.pool_lba)
+ return block;
- if (block < bmtd.pool_lba)
- mapping_block = bmtd.bbt->bb_tbl[block];
- else
- mapping_block = block;
- BBT_LOG("0x%x mapped to 0x%x", block, mapping_block);
+ if (!mapping_block_in_range(block))
+ return block;
- return mapping_block;
+ return bmtd.bbt->bb_tbl[block];
}
static int
@@ -839,6 +857,10 @@ int mtk_bmt_attach(struct mtd_info *mtd)
&bmt_table_size) != 0)
bmt_table_size = 0x2000U;
+ bmtd.remap_range = of_get_property(np, "mediatek,bmt-remap-range",
+ &bmtd.remap_range_len);
+ bmtd.remap_range_len /= 8;
+
bmtd.mtd = mtd;
mtk_bmt_replace_ops(mtd);