summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2013-12-31 08:42:13 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2013-12-31 08:42:12 -0800
commit4bed7076009d4337e695b92f977668837f20111a (patch)
tree07cd449b895c262cec0e4ef3e1fd1fd497038434 /drivers/mtd
parent69556ccbbb622909b0edaddef68ad9c4e7c999c9 (diff)
parent555a56b89a9403091f6bcebbe9f6bd661dd49c59 (diff)
Merge "mtd: msm_qpic_nand: Support for multi page read"
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/devices/msm_qpic_nand.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c
index cca5c8cc5c1b..eb671295aba3 100644
--- a/drivers/mtd/devices/msm_qpic_nand.c
+++ b/drivers/mtd/devices/msm_qpic_nand.c
@@ -1828,19 +1828,46 @@ static int msm_nand_read(struct mtd_info *mtd, loff_t from, size_t len,
struct mtd_oob_ops ops;
ops.mode = MTD_OPS_AUTO_OOB;
- ops.len = len;
ops.retlen = 0;
ops.ooblen = 0;
- ops.datbuf = buf;
ops.oobbuf = NULL;
- if (!(from & (mtd->writesize - 1)) && !(len % mtd->writesize))
- /* read pages on page boundary */
- ret = msm_nand_read_oob(mtd, from, &ops);
- else
+ if (!(from & (mtd->writesize - 1)) && !(len % mtd->writesize)) {
+ /*
+ * Handle reading of large size read buffer in vmalloc
+ * address space that does not fit in an MMU page.
+ */
+ if (!virt_addr_valid(buf) &&
+ ((unsigned long) buf & ~PAGE_MASK) + len > PAGE_SIZE) {
+ ops.len = mtd->writesize;
+
+ for (;;) {
+ ops.datbuf = buf;
+ ret = msm_nand_read_oob(mtd, from, &ops);
+ if (ret < 0)
+ break;
+
+ len -= mtd->writesize;
+ *retlen += mtd->writesize;
+ if (len == 0)
+ break;
+
+ buf += mtd->writesize;
+ from += mtd->writesize;
+ }
+ } else {
+ ops.len = len;
+ ops.datbuf = buf;
+ ret = msm_nand_read_oob(mtd, from, &ops);
+ *retlen = ops.retlen;
+ }
+ } else {
+ ops.len = len;
+ ops.datbuf = buf;
ret = msm_nand_read_partial_page(mtd, from, &ops);
+ *retlen = ops.retlen;
+ }
- *retlen = ops.retlen;
return ret;
}