From d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 02:45:28 +0000
Subject: [PATCH] add boot partition  size

---
 kernel/drivers/rk_nand/rk_nand_blk.c |  666 +++++++++++++++++++++---------------------------------
 1 files changed, 262 insertions(+), 404 deletions(-)

diff --git a/kernel/drivers/rk_nand/rk_nand_blk.c b/kernel/drivers/rk_nand/rk_nand_blk.c
index 3bf533b..5cb6033 100644
--- a/kernel/drivers/rk_nand/rk_nand_blk.c
+++ b/kernel/drivers/rk_nand/rk_nand_blk.c
@@ -7,12 +7,15 @@
  * (at your option) any later version.
  */
 
+#define pr_fmt(fmt) "rk_nand: " fmt
+
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/fs.h>
 #include <linux/blkdev.h>
+#include <linux/blk-mq.h>
 #include <linux/blkpg.h>
 #include <linux/spinlock.h>
 #include <linux/hdreg.h>
@@ -36,9 +39,6 @@
 #include "rk_nand_blk.h"
 #include "rk_ftl_api.h"
 
-static struct nand_part disk_array[MAX_PART_COUNT];
-static int g_max_part_num = 4;
-
 #define PART_READONLY 0x85
 #define PART_WRITEONLY 0x86
 #define PART_NO_ACCESS 0x87
@@ -48,10 +48,17 @@
 static unsigned long totle_read_count;
 static unsigned long totle_write_count;
 static int rk_nand_dev_initialised;
+static unsigned long rk_ftl_gc_do;
+static DECLARE_WAIT_QUEUE_HEAD(rknand_thread_wait);
+static unsigned long rk_ftl_gc_jiffies;
 
 static char *mtd_read_temp_buffer;
 #define MTD_RW_SECTORS (512)
 
+#define DISABLE_WRITE _IO('V', 0)
+#define ENABLE_WRITE _IO('V', 1)
+#define DISABLE_READ _IO('V', 2)
+#define ENABLE_READ _IO('V', 3)
 static int rknand_proc_show(struct seq_file *m, void *v)
 {
 	m->count = rknand_proc_ftlread(m->buf);
@@ -62,43 +69,16 @@
 	return 0;
 }
 
-static int rknand_mtd_proc_show(struct seq_file *m, void *v)
-{
-	int i;
-
-	seq_printf(m, "%s", "dev:    size   erasesize  name\n");
-	for (i = 0; i < g_max_part_num; i++) {
-		seq_printf(m, "rknand%d: %8.8llx %8.8x \"%s\"\n", i,
-			   (unsigned long long)disk_array[i].size * 512,
-			   32 * 0x200, disk_array[i].name);
-	}
-	return 0;
-}
-
 static int rknand_proc_open(struct inode *inode, struct file *file)
 {
 	return single_open(file, rknand_proc_show, PDE_DATA(inode));
 }
 
-static int rknand_mtd_proc_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, rknand_mtd_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations rknand_proc_fops = {
-	.owner		= THIS_MODULE,
-	.open		= rknand_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static const struct file_operations rknand_mtd_proc_fops = {
-	.owner		= THIS_MODULE,
-	.open		= rknand_mtd_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
+static const struct proc_ops rknand_proc_fops = {
+	.proc_open	= rknand_proc_open,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= single_release,
 };
 
 static int rknand_create_procfs(void)
@@ -110,10 +90,6 @@
 	if (!ent)
 		return -1;
 
-	ent = proc_create_data("mtd", 0444, NULL, &rknand_mtd_proc_fops,
-			       (void *)0);
-	if (!ent)
-		return -1;
 	return 0;
 }
 
@@ -143,8 +119,7 @@
 			     unsigned long start,
 			     unsigned long nsector,
 			     char *buf,
-			     int cmd,
-			     int totle_nsec)
+			     int cmd)
 {
 	int ret;
 
@@ -155,7 +130,6 @@
 	}
 
 	start += dev->off_size;
-	rknand_device_lock();
 
 	switch (cmd) {
 	case READ:
@@ -179,22 +153,7 @@
 		break;
 	}
 
-	rknand_device_unlock();
 	return ret;
-}
-
-static DECLARE_WAIT_QUEUE_HEAD(rknand_thread_wait);
-static void rk_ftl_gc_timeout_hack(struct timer_list *unused);
-static DEFINE_TIMER(rk_ftl_gc_timeout, rk_ftl_gc_timeout_hack);
-static unsigned long rk_ftl_gc_jiffies;
-static unsigned long rk_ftl_gc_do;
-
-static void rk_ftl_gc_timeout_hack(struct timer_list *unused)
-{
-	del_timer(&rk_ftl_gc_timeout);
-	rk_ftl_gc_do++;
-	rk_ftl_gc_timeout.expires = jiffies + rk_ftl_gc_jiffies * rk_ftl_gc_do;
-	add_timer(&rk_ftl_gc_timeout);
 }
 
 static int req_check_buffer_align(struct request *req, char **pbuf)
@@ -225,284 +184,201 @@
 	return 1;
 }
 
-static int nand_blktrans_thread(void *arg)
+static blk_status_t do_blktrans_all_request(struct nand_blk_dev *dev,
+					    struct request *req)
 {
-	struct nand_blk_ops *nandr = arg;
-	struct request_queue *rq = nandr->rq;
-	struct request *req = NULL;
-	int ftl_gc_status = 0;
-	char *buf, *page_buf;
+	unsigned long block, nsect;
+	char *buf = NULL, *page_buf;
 	struct req_iterator rq_iter;
 	struct bio_vec bvec;
-	unsigned long long sector_index = ULLONG_MAX;
+	int ret = BLK_STS_IOERR;
 	unsigned long totle_nsect;
-	int rw_flag = 0;
-	int req_empty_times = 0;
-	int op;
 
-	spin_lock_irq(rq->queue_lock);
-	rk_ftl_gc_jiffies = HZ / 10; /* do garbage collect after 100ms */
+	block = blk_rq_pos(req);
+	nsect = blk_rq_cur_bytes(req) >> 9;
+	totle_nsect = (req->__data_len) >> 9;
+
+	if (blk_rq_pos(req) + blk_rq_cur_sectors(req) > get_capacity(req->rq_disk))
+		return BLK_STS_IOERR;
+
+	switch (req_op(req)) {
+	case REQ_OP_DISCARD:
+		if (FtlDiscard(block, nsect))
+			return BLK_STS_IOERR;
+		return BLK_STS_OK;
+	case REQ_OP_READ:
+		buf = mtd_read_temp_buffer;
+		req_check_buffer_align(req, &buf);
+		ret = nand_dev_transfer(dev, block, totle_nsect, buf, REQ_OP_READ);
+		if (buf == mtd_read_temp_buffer) {
+			char *p = buf;
+
+			rq_for_each_segment(bvec, req, rq_iter) {
+				page_buf = kmap_atomic(bvec.bv_page);
+
+				memcpy(page_buf + bvec.bv_offset, p, bvec.bv_len);
+				p += bvec.bv_len;
+				kunmap_atomic(page_buf);
+			}
+		}
+
+		if (ret)
+			return BLK_STS_IOERR;
+		else
+			return BLK_STS_OK;
+	case REQ_OP_WRITE:
+		buf = mtd_read_temp_buffer;
+		req_check_buffer_align(req, &buf);
+
+		if (buf == mtd_read_temp_buffer) {
+			char *p = buf;
+
+			rq_for_each_segment(bvec, req, rq_iter) {
+				page_buf = kmap_atomic(bvec.bv_page);
+				memcpy(p, page_buf + bvec.bv_offset, bvec.bv_len);
+				p += bvec.bv_len;
+				kunmap_atomic(page_buf);
+			}
+		}
+
+		ret = nand_dev_transfer(dev, block, totle_nsect, buf, REQ_OP_WRITE);
+
+		if (ret)
+			return BLK_STS_IOERR;
+		else
+			return BLK_STS_OK;
+
+	default:
+		return BLK_STS_IOERR;
+	}
+}
+
+static struct request *rk_nand_next_request(struct nand_blk_dev *dev)
+{
+	struct nand_blk_ops *nand_ops = dev->nand_ops;
+	struct request *rq;
+
+	rq = list_first_entry_or_null(&nand_ops->rq_list, struct request, queuelist);
+	if (rq) {
+		list_del_init(&rq->queuelist);
+		blk_mq_start_request(rq);
+		return rq;
+	}
+
+	return NULL;
+}
+
+static void rk_nand_blktrans_work(struct nand_blk_dev *dev)
+	__releases(&dev->nand_ops->queue_lock)
+	__acquires(&dev->nand_ops->queue_lock)
+{
+	struct request *req = NULL;
+
+	while (1) {
+		blk_status_t res;
+
+		req = rk_nand_next_request(dev);
+		if (!req)
+			break;
+
+		spin_unlock_irq(&dev->nand_ops->queue_lock);
+
+		rknand_device_lock();
+		res = do_blktrans_all_request(dev, req);
+		rknand_device_unlock();
+
+		if (!blk_update_request(req, res, req->__data_len)) {
+			__blk_mq_end_request(req, res);
+			req = NULL;
+		}
+
+		spin_lock_irq(&dev->nand_ops->queue_lock);
+	}
+}
+
+static blk_status_t rk_nand_queue_rq(struct blk_mq_hw_ctx *hctx,
+				     const struct blk_mq_queue_data *bd)
+{
+	struct nand_blk_dev *dev;
+
+	dev = hctx->queue->queuedata;
+	if (!dev) {
+		blk_mq_start_request(bd->rq);
+		return BLK_STS_IOERR;
+	}
+
 	rk_ftl_gc_do = 0;
-	rk_ftl_gc_timeout.expires = jiffies + rk_ftl_gc_jiffies;
-	add_timer(&rk_ftl_gc_timeout);
+	spin_lock_irq(&dev->nand_ops->queue_lock);
+	list_add_tail(&bd->rq->queuelist, &dev->nand_ops->rq_list);
+	rk_nand_blktrans_work(dev);
+	spin_unlock_irq(&dev->nand_ops->queue_lock);
 
-	while (!nandr->quit) {
-		int res;
-		struct nand_blk_dev *dev;
+	/* wake up gc thread */
+	rk_ftl_gc_do = 1;
+	wake_up(&dev->nand_ops->thread_wq);
+
+	return BLK_STS_OK;
+}
+
+static const struct blk_mq_ops rk_nand_mq_ops = {
+	.queue_rq	= rk_nand_queue_rq,
+};
+
+static int nand_gc_thread(void *arg)
+{
+	struct nand_blk_ops *nand_ops = arg;
+	int ftl_gc_status = 0;
+	int req_empty_times = 0;
+	int gc_done_times = 0;
+
+	rk_ftl_gc_jiffies = HZ / 10;
+	rk_ftl_gc_do = 1;
+
+	while (!nand_ops->quit) {
 		DECLARE_WAITQUEUE(wait, current);
 
-		if (!req)
-			req = blk_fetch_request(rq);
-		if (!req) {
-			add_wait_queue(&nandr->thread_wq, &wait);
-			set_current_state(TASK_INTERRUPTIBLE);
-			spin_unlock_irq(rq->queue_lock);
+		add_wait_queue(&nand_ops->thread_wq, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (rk_ftl_gc_do) {
+			 /* do garbage collect at idle state */
 			if (rknand_device_trylock()) {
 				ftl_gc_status = rk_ftl_garbage_collect(1, 0);
 				rknand_device_unlock();
 				rk_ftl_gc_jiffies = HZ / 50;
-				if (ftl_gc_status == 0)
-					rk_ftl_gc_jiffies = 1 * HZ;
-
+				if (ftl_gc_status == 0) {
+					gc_done_times++;
+					if (gc_done_times > 10)
+						rk_ftl_gc_jiffies = 10 * HZ;
+					else
+						rk_ftl_gc_jiffies = 1 * HZ;
+				} else {
+					gc_done_times = 0;
+				}
 			} else {
-				rk_ftl_gc_jiffies = HZ / 50;
+				rk_ftl_gc_jiffies = 1 * HZ;
 			}
 			req_empty_times++;
 			if (req_empty_times < 10)
 				rk_ftl_gc_jiffies = HZ / 50;
-			/* 100ms cache write back */
+			/* cache write back after 100ms */
 			if (req_empty_times >= 5 && req_empty_times < 7) {
 				rknand_device_lock();
 				rk_ftl_cache_write_back();
 				rknand_device_unlock();
 			}
-			wait_event_timeout(nandr->thread_wq,
-					   rk_ftl_gc_do || nandr->quit,
-					   rk_ftl_gc_jiffies);
-			rk_ftl_gc_do = 0;
-			spin_lock_irq(rq->queue_lock);
-			remove_wait_queue(&nandr->thread_wq, &wait);
-			continue;
 		} else {
-			rk_ftl_gc_jiffies = 1 * HZ;
 			req_empty_times = 0;
+			rk_ftl_gc_jiffies = 1 * HZ;
 		}
-
-		dev = req->rq_disk->private_data;
-		totle_nsect = (req->__data_len) >> 9;
-		sector_index = blk_rq_pos(req);
-		buf = 0;
-		res = 0;
-
-		op = req_op(req);
-		if (op == REQ_OP_DISCARD) {
-			spin_unlock_irq(rq->queue_lock);
-			rknand_device_lock();
-			if (FtlDiscard(blk_rq_pos(req) +
-				       dev->off_size, totle_nsect))
-				res = BLK_STS_IOERR;
-			rknand_device_unlock();
-			spin_lock_irq(rq->queue_lock);
-			if (!__blk_end_request_cur(req, res))
-				req = NULL;
-			continue;
-		} else if (op == REQ_OP_FLUSH) {
-			spin_unlock_irq(rq->queue_lock);
-			rknand_device_lock();
-			rk_ftl_cache_write_back();
-			rknand_device_unlock();
-			spin_lock_irq(rq->queue_lock);
-			if (!__blk_end_request_cur(req, res))
-				req = NULL;
-			continue;
-		} else if (op == REQ_OP_READ) {
-			rw_flag = READ;
-		} else if (op == REQ_OP_WRITE) {
-			rw_flag = WRITE;
-		} else {
-			__blk_end_request_all(req, BLK_STS_IOERR);
-			req = NULL;
-			continue;
-		}
-
-		if (mtd_read_temp_buffer) {
-			buf = mtd_read_temp_buffer;
-			req_check_buffer_align(req, &buf);
-
-			if (rw_flag == WRITE && buf == mtd_read_temp_buffer) {
-				char *p = buf;
-
-				rq_for_each_segment(bvec, req, rq_iter) {
-					page_buf = kmap_atomic(bvec.bv_page);
-					memcpy(p,
-					       page_buf + bvec.bv_offset,
-					       bvec.bv_len);
-					p += bvec.bv_len;
-					kunmap_atomic(page_buf);
-				}
-			}
-
-			spin_unlock_irq(rq->queue_lock);
-			res = nand_dev_transfer(dev,
-						sector_index,
-						totle_nsect,
-						buf,
-						rw_flag,
-						totle_nsect);
-			spin_lock_irq(rq->queue_lock);
-
-			if (rw_flag == READ && buf == mtd_read_temp_buffer) {
-				char *p = buf;
-
-				rq_for_each_segment(bvec, req, rq_iter) {
-					page_buf = kmap_atomic(bvec.bv_page);
-
-					memcpy(page_buf + bvec.bv_offset,
-					       p,
-					       bvec.bv_len);
-					p += bvec.bv_len;
-					kunmap_atomic(page_buf);
-				}
-			}
-			__blk_end_request_all(req, res);
-			req = NULL;
-		} else {
-			while (req) {
-				sector_index = blk_rq_pos(req);
-				totle_nsect = blk_rq_cur_bytes(req);
-				buf = kmap_atomic(bio_page(req->bio)) +
-					   bio_offset(req->bio);
-				spin_unlock_irq(rq->queue_lock);
-				res = nand_dev_transfer(dev,
-							sector_index,
-							totle_nsect,
-							buf,
-							rw_flag,
-							totle_nsect);
-				spin_lock_irq(rq->queue_lock);
-				kunmap_atomic(buf);
-				if (!__blk_end_request_cur(req, res))
-					req = NULL;
-			}
-		}
+		wait_event_timeout(nand_ops->thread_wq, nand_ops->quit,
+				   rk_ftl_gc_jiffies);
+		remove_wait_queue(&nand_ops->thread_wq, &wait);
+		continue;
 	}
-	pr_info("nand th quited\n");
-	nandr->nand_th_quited = 1;
-	if (req)
-		__blk_end_request_all(req, BLK_STS_IOERR);
-	rk_nand_schedule_enable_config(0);
-	while ((req = blk_fetch_request(rq)) != NULL)
-		__blk_end_request_all(req, BLK_STS_IOERR);
-	spin_unlock_irq(rq->queue_lock);
-	complete_and_exit(&nandr->thread_exit, 0);
-	return 0;
-}
-
-static void nand_blk_request(struct request_queue *rq)
-{
-	struct nand_blk_ops *nandr = rq->queuedata;
-	struct request *req = NULL;
-
-	if (nandr->nand_th_quited) {
-		while ((req = blk_fetch_request(rq)) != NULL)
-			__blk_end_request_all(req, BLK_STS_IOERR);
-		return;
-	}
-	rk_ftl_gc_do = 1;
-	wake_up(&nandr->thread_wq);
-}
-
-static int rknand_get_part(char *parts,
-			   struct nand_part *this_part,
-			   int *part_index)
-{
-	char delim;
-	unsigned int mask_flags;
-	unsigned long long size, offset = ULLONG_MAX;
-	char name[40] = "\0";
-
-	if (*parts == '-') {
-		size = ULLONG_MAX;
-		parts++;
-	} else {
-		size = memparse(parts, &parts);
-	}
-
-	if (*parts == '@') {
-		parts++;
-		offset = memparse(parts, &parts);
-	}
-
-	mask_flags = 0;
-	delim = 0;
-
-	if (*parts == '(')
-		delim = ')';
-
-	if (delim) {
-		char *p;
-
-		p = strchr(parts + 1, delim);
-		if (!p)
-			return 0;
-		strncpy(name, parts + 1, p - (parts + 1));
-		parts = p + 1;
-	}
-
-	if (strncmp(parts, "ro", 2) == 0) {
-		mask_flags = PART_READONLY;
-		parts += 2;
-	}
-
-	if (strncmp(parts, "wo", 2) == 0) {
-		mask_flags = PART_WRITEONLY;
-		parts += 2;
-	}
-
-	this_part->size = (unsigned long)size;
-	this_part->offset = (unsigned long)offset;
-	this_part->type = mask_flags;
-	sprintf(this_part->name, "%s", name);
-
-	if ((++(*part_index) < MAX_PART_COUNT) && (*parts == ','))
-		rknand_get_part(++parts, this_part + 1, part_index);
-
-	return 1;
-}
-
-static int nand_prase_cmdline_part(struct nand_part *pdisk_part)
-{
-	char *pbuf;
-	int part_num = 0, i;
-	unsigned int cap_size = rk_ftl_get_capacity();
-	char *cmdline;
-
-	cmdline = strstr(saved_command_line, "mtdparts=");
-	if (!cmdline)
-		return 0;
-	cmdline += 9;
-	if (!memcmp(cmdline, "rk29xxnand:", strlen("rk29xxnand:"))) {
-		pbuf = cmdline + strlen("rk29xxnand:");
-		rknand_get_part(pbuf, pdisk_part, &part_num);
-		if (part_num)
-			pdisk_part[part_num - 1].size = cap_size -
-				pdisk_part[part_num - 1].offset;
-
-		for (i = 0; i < part_num; i++) {
-			if (pdisk_part[i].size + pdisk_part[i].offset
-				> cap_size) {
-				pdisk_part[i].size = cap_size -
-					pdisk_part[i].offset;
-				pr_err("partition error....max cap:%x\n",
-					cap_size);
-				if (!pdisk_part[i].size)
-					return i;
-				else
-					return (i + 1);
-			}
-		}
-		return part_num;
-	}
+	pr_info("nand gc quited\n");
+	nand_ops->nand_th_quited = 1;
+	complete_and_exit(&nand_ops->thread_exit, 0);
 	return 0;
 }
 
@@ -515,10 +391,6 @@
 {
 };
 
-#define DISABLE_WRITE _IO('V', 0)
-#define ENABLE_WRITE _IO('V', 1)
-#define DISABLE_READ _IO('V', 2)
-#define ENABLE_READ _IO('V', 3)
 static int rknand_ioctl(struct block_device *bdev, fmode_t mode,
 			unsigned int cmd,
 			unsigned long arg)
@@ -564,7 +436,7 @@
 	.owner = THIS_MODULE,
 };
 
-static int nand_add_dev(struct nand_blk_ops *nandr, struct nand_part *part)
+static int nand_add_dev(struct nand_blk_ops *nand_ops, struct nand_part *part)
 {
 	struct nand_blk_dev *dev;
 	struct gendisk *gd;
@@ -576,45 +448,37 @@
 	if (!dev)
 		return -ENOMEM;
 
-	gd = alloc_disk(1 << nandr->minorbits);
+	gd = alloc_disk(1 << nand_ops->minorbits);
 	if (!gd) {
 		kfree(dev);
 		return -ENOMEM;
 	}
-
-	dev->nandr = nandr;
+	nand_ops->rq->queuedata = dev;
+	dev->nand_ops = nand_ops;
 	dev->size = part->size;
 	dev->off_size = part->offset;
-	dev->devnum = nandr->last_dev_index;
-	list_add_tail(&dev->list, &nandr->devs);
-	nandr->last_dev_index++;
+	dev->devnum = nand_ops->last_dev_index;
+	list_add_tail(&dev->list, &nand_ops->devs);
+	nand_ops->last_dev_index++;
 
-	gd->major = nandr->major;
-	gd->first_minor = (dev->devnum) << nandr->minorbits;
+	gd->major = nand_ops->major;
+	gd->first_minor = (dev->devnum) << nand_ops->minorbits;
 
 	gd->fops = &nand_blktrans_ops;
 
-	if (part->name[0]) {
-		snprintf(gd->disk_name,
-			 sizeof(gd->disk_name),
-			 "%s_%s",
-			 nandr->name,
-			 part->name);
-	} else {
-		gd->flags = GENHD_FL_EXT_DEVT;
-		gd->minors = 255;
-		snprintf(gd->disk_name,
-			 sizeof(gd->disk_name),
-			 "%s%d",
-			 nandr->name,
-			 dev->devnum);
-	}
+	gd->flags = GENHD_FL_EXT_DEVT;
+	gd->minors = 255;
+	snprintf(gd->disk_name,
+		 sizeof(gd->disk_name),
+		 "%s%d",
+		 nand_ops->name,
+		 dev->devnum);
+
 	set_capacity(gd, dev->size);
 
 	gd->private_data = dev;
 	dev->blkcore_priv = gd;
-	gd->queue = nandr->rq;
-	gd->queue->bypass_depth = 1;
+	gd->queue = nand_ops->rq;
 
 	if (part->type == PART_NO_ACCESS)
 		dev->disable_access = 1;
@@ -628,10 +492,7 @@
 	if (dev->readonly)
 		set_disk_ro(gd, 1);
 
-	if (gd->flags != GENHD_FL_EXT_DEVT)
-		add_disk(gd);
-	else
-		device_add_disk(g_nand_device, gd);
+	device_add_disk(g_nand_device, gd, NULL);
 
 	return 0;
 }
@@ -646,81 +507,68 @@
 	del_gendisk(gd);
 	put_disk(gd);
 	kfree(dev);
+
 	return 0;
 }
 
-int nand_blk_add_whole_disk(void)
+static int nand_blk_register(struct nand_blk_ops *nand_ops)
 {
 	struct nand_part part;
-
-	part.offset = 0;
-	part.size = rk_ftl_get_capacity();
-	part.type = 0;
-	strncpy(part.name, "rknand", sizeof(part.name));
-	nand_add_dev(&mytr, &part);
-	return 0;
-}
-
-static int nand_blk_register(struct nand_blk_ops *nandr)
-{
-	int i, ret;
-	u32 part_size;
-	struct nand_part part;
+	int ret;
 
 	rk_nand_schedule_enable_config(1);
-	nandr->quit = 0;
-	nandr->nand_th_quited = 0;
+	nand_ops->quit = 0;
+	nand_ops->nand_th_quited = 0;
 
-	mtd_read_temp_buffer = kmalloc(MTD_RW_SECTORS * 512,
-				       GFP_KERNEL | GFP_DMA);
-
-	ret = register_blkdev(nandr->major, nandr->name);
+	ret = register_blkdev(nand_ops->major, nand_ops->name);
 	if (ret)
-		return -1;
+		return ret;
 
-	spin_lock_init(&nandr->queue_lock);
-	init_completion(&nandr->thread_exit);
-	init_waitqueue_head(&nandr->thread_wq);
-	rknand_device_lock_init();
-
-	nandr->rq = blk_init_queue(nand_blk_request, &nandr->queue_lock);
-	if (!nandr->rq) {
-		unregister_blkdev(nandr->major, nandr->name);
-		return  -1;
+	mtd_read_temp_buffer = kmalloc(MTD_RW_SECTORS * 512, GFP_KERNEL | GFP_DMA);
+	if (!mtd_read_temp_buffer) {
+		ret = -ENOMEM;
+		goto mtd_buffer_error;
 	}
 
-	blk_queue_max_hw_sectors(nandr->rq, MTD_RW_SECTORS);
-	blk_queue_max_segments(nandr->rq, MTD_RW_SECTORS);
+	init_completion(&nand_ops->thread_exit);
+	init_waitqueue_head(&nand_ops->thread_wq);
+	rknand_device_lock_init();
 
-	blk_queue_flag_set(QUEUE_FLAG_DISCARD, nandr->rq);
-	blk_queue_max_discard_sectors(nandr->rq, UINT_MAX >> 9);
+	/* Create the request queue */
+	spin_lock_init(&nand_ops->queue_lock);
+	INIT_LIST_HEAD(&nand_ops->rq_list);
+
+	nand_ops->tag_set = kzalloc(sizeof(*nand_ops->tag_set), GFP_KERNEL);
+	if (!nand_ops->tag_set) {
+		ret = -ENOMEM;
+		goto tag_set_error;
+	}
+
+	nand_ops->rq = blk_mq_init_sq_queue(nand_ops->tag_set, &rk_nand_mq_ops, 1,
+					   BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING);
+	if (IS_ERR(nand_ops->rq)) {
+		ret = PTR_ERR(nand_ops->rq);
+		nand_ops->rq = NULL;
+		goto rq_init_error;
+	}
+
+	blk_queue_max_hw_sectors(nand_ops->rq, MTD_RW_SECTORS);
+	blk_queue_max_segments(nand_ops->rq, MTD_RW_SECTORS);
+
+	blk_queue_flag_set(QUEUE_FLAG_DISCARD, nand_ops->rq);
+	blk_queue_max_discard_sectors(nand_ops->rq, UINT_MAX >> 9);
 	/* discard_granularity config to one nand page size 32KB*/
-	nandr->rq->limits.discard_granularity = 64 << 9;
+	nand_ops->rq->limits.discard_granularity = 64 << 9;
 
-	nandr->rq->queuedata = nandr;
-	INIT_LIST_HEAD(&nandr->devs);
-	kthread_run(nand_blktrans_thread, (void *)nandr, "rknand");
+	INIT_LIST_HEAD(&nand_ops->devs);
+	kthread_run(nand_gc_thread, (void *)nand_ops, "rknand_gc");
 
-	g_max_part_num = nand_prase_cmdline_part(disk_array);
-
-	nandr->last_dev_index = 0;
+	nand_ops->last_dev_index = 0;
 	part.offset = 0;
 	part.size = rk_ftl_get_capacity();
 	part.type = 0;
 	part.name[0] = 0;
-	nand_add_dev(&mytr, &part);
-
-	if (g_max_part_num) {
-		for (i = 0; i < g_max_part_num; i++) {
-			part_size = (disk_array[i].offset + disk_array[i].size);
-			pr_info("%10s: 0x%09llx -- 0x%09llx (%llu MB)\n",
-				disk_array[i].name,
-				(u64)disk_array[i].offset * 512,
-				(u64)part_size * 512,
-				(u64)disk_array[i].size / 2048);
-			nand_add_dev(nandr, &disk_array[i]);
-		}
-	}
+	nand_add_dev(nand_ops, &part);
 
 	rknand_create_procfs();
 	rk_ftl_storage_sys_init();
@@ -735,25 +583,35 @@
 	}
 
 	return 0;
+
+rq_init_error:
+	kfree(nand_ops->tag_set);
+tag_set_error:
+	kfree(mtd_read_temp_buffer);
+	mtd_read_temp_buffer = NULL;
+mtd_buffer_error:
+	unregister_blkdev(nand_ops->major, nand_ops->name);
+
+	return ret;
 }
 
-static void nand_blk_unregister(struct nand_blk_ops *nandr)
+static void nand_blk_unregister(struct nand_blk_ops *nand_ops)
 {
 	struct list_head *this, *next;
 
 	if (!rk_nand_dev_initialised)
 		return;
-	nandr->quit = 1;
-	wake_up(&nandr->thread_wq);
-	wait_for_completion(&nandr->thread_exit);
-	list_for_each_safe(this, next, &nandr->devs) {
+	nand_ops->quit = 1;
+	wake_up(&nand_ops->thread_wq);
+	wait_for_completion(&nand_ops->thread_exit);
+	list_for_each_safe(this, next, &nand_ops->devs) {
 		struct nand_blk_dev *dev
 			= list_entry(this, struct nand_blk_dev, list);
 
 		nand_remove_dev(dev);
 	}
-	blk_cleanup_queue(nandr->rq);
-	unregister_blkdev(nandr->major, nandr->name);
+	blk_cleanup_queue(nand_ops->rq);
+	unregister_blkdev(nand_ops->major, nand_ops->name);
 }
 
 void rknand_dev_flush(void)

--
Gitblit v1.6.2