+ return 0;
+}
+
+int mtk_bmt_attach(struct mtd_info *mtd)
+{
+ static const struct mtk_bmt_ops v2_ops = {
+ .sig = "bmt",
+ .sig_len = 3,
+ .init = mtk_bmt_init_v2,
+ .remap_block = remap_block_v2,
+ .unmap_block = unmap_block_v2,
+ .get_mapping_block = get_mapping_block_index_v2,
+ .debug = mtk_bmt_debug_v2,
+ };
+ struct device_node *np;
+ int ret = 0;
+
+ if (bmtd.mtd)
+ return -ENOSPC;
+
+ np = mtd_get_of_node(mtd);
+ if (!np)
+ return 0;
+
+ if (of_property_read_bool(np, "mediatek,bmt-v2"))
+ bmtd.ops = &v2_ops;
+ else
+ return 0;
+
+ 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);
+
+ bmtd.blk_size = mtd->erasesize;
+ bmtd.blk_shift = ffs(bmtd.blk_size) - 1;
+ bmtd.pg_size = mtd->writesize;
+ bmtd.pg_shift = ffs(bmtd.pg_size) - 1;
+ bmtd.total_blks = mtd->size >> bmtd.blk_shift;
+
+ nand_data_buf = kzalloc(bmtd.pg_size, GFP_KERNEL);
+ if (!nand_data_buf) {
+ pr_info("nand: FATAL ERR: allocate buffer failed!\n");
+ ret = -1;
+ goto error;
+ }
+
+ memset(nand_data_buf, 0xff, bmtd.pg_size);
+
+ ret = bmtd.ops->init(np);
+ if (ret)
+ goto error;
+
+ mtk_bmt_add_debugfs();