aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/lpddr
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/mtd/lpddr
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/mtd/lpddr')
-rw-r--r--drivers/mtd/lpddr/lpddr_cmds.c45
-rw-r--r--drivers/mtd/lpddr/qinfo_probe.c2
2 files changed, 28 insertions, 19 deletions
diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c
index d3cfe26beea..65655dd59e1 100644
--- a/drivers/mtd/lpddr/lpddr_cmds.c
+++ b/drivers/mtd/lpddr/lpddr_cmds.c
@@ -27,7 +27,6 @@
27#include <linux/mtd/pfow.h> 27#include <linux/mtd/pfow.h>
28#include <linux/mtd/qinfo.h> 28#include <linux/mtd/qinfo.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/module.h>
31 30
32static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len, 31static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
33 size_t *retlen, u_char *buf); 32 size_t *retlen, u_char *buf);
@@ -40,7 +39,7 @@ static int lpddr_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
40static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); 39static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
41static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, 40static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
42 size_t *retlen, void **mtdbuf, resource_size_t *phys); 41 size_t *retlen, void **mtdbuf, resource_size_t *phys);
43static int lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len); 42static void lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len);
44static int get_chip(struct map_info *map, struct flchip *chip, int mode); 43static int get_chip(struct map_info *map, struct flchip *chip, int mode);
45static int chip_ready(struct map_info *map, struct flchip *chip, int mode); 44static int chip_ready(struct map_info *map, struct flchip *chip, int mode);
46static void put_chip(struct map_info *map, struct flchip *chip); 45static void put_chip(struct map_info *map, struct flchip *chip);
@@ -63,19 +62,26 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
63 mtd->type = MTD_NORFLASH; 62 mtd->type = MTD_NORFLASH;
64 63
65 /* Fill in the default mtd operations */ 64 /* Fill in the default mtd operations */
66 mtd->_read = lpddr_read; 65 mtd->read = lpddr_read;
67 mtd->type = MTD_NORFLASH; 66 mtd->type = MTD_NORFLASH;
68 mtd->flags = MTD_CAP_NORFLASH; 67 mtd->flags = MTD_CAP_NORFLASH;
69 mtd->flags &= ~MTD_BIT_WRITEABLE; 68 mtd->flags &= ~MTD_BIT_WRITEABLE;
70 mtd->_erase = lpddr_erase; 69 mtd->erase = lpddr_erase;
71 mtd->_write = lpddr_write_buffers; 70 mtd->write = lpddr_write_buffers;
72 mtd->_writev = lpddr_writev; 71 mtd->writev = lpddr_writev;
73 mtd->_lock = lpddr_lock; 72 mtd->read_oob = NULL;
74 mtd->_unlock = lpddr_unlock; 73 mtd->write_oob = NULL;
74 mtd->sync = NULL;
75 mtd->lock = lpddr_lock;
76 mtd->unlock = lpddr_unlock;
77 mtd->suspend = NULL;
78 mtd->resume = NULL;
75 if (map_is_linear(map)) { 79 if (map_is_linear(map)) {
76 mtd->_point = lpddr_point; 80 mtd->point = lpddr_point;
77 mtd->_unpoint = lpddr_unpoint; 81 mtd->unpoint = lpddr_unpoint;
78 } 82 }
83 mtd->block_isbad = NULL;
84 mtd->block_markbad = NULL;
79 mtd->size = 1 << lpddr->qinfo->DevSizeShift; 85 mtd->size = 1 << lpddr->qinfo->DevSizeShift;
80 mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift; 86 mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift;
81 mtd->writesize = 1 << lpddr->qinfo->BufSizeShift; 87 mtd->writesize = 1 << lpddr->qinfo->BufSizeShift;
@@ -530,12 +536,14 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
530 struct flchip *chip = &lpddr->chips[chipnum]; 536 struct flchip *chip = &lpddr->chips[chipnum];
531 int ret = 0; 537 int ret = 0;
532 538
533 if (!map->virt) 539 if (!map->virt || (adr + len > mtd->size))
534 return -EINVAL; 540 return -EINVAL;
535 541
536 /* ofs: offset within the first chip that the first read should start */ 542 /* ofs: offset within the first chip that the first read should start */
537 ofs = adr - (chipnum << lpddr->chipshift); 543 ofs = adr - (chipnum << lpddr->chipshift);
544
538 *mtdbuf = (void *)map->virt + chip->start + ofs; 545 *mtdbuf = (void *)map->virt + chip->start + ofs;
546 *retlen = 0;
539 547
540 while (len) { 548 while (len) {
541 unsigned long thislen; 549 unsigned long thislen;
@@ -573,11 +581,11 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
573 return 0; 581 return 0;
574} 582}
575 583
576static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) 584static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
577{ 585{
578 struct map_info *map = mtd->priv; 586 struct map_info *map = mtd->priv;
579 struct lpddr_private *lpddr = map->fldrv_priv; 587 struct lpddr_private *lpddr = map->fldrv_priv;
580 int chipnum = adr >> lpddr->chipshift, err = 0; 588 int chipnum = adr >> lpddr->chipshift;
581 unsigned long ofs; 589 unsigned long ofs;
582 590
583 /* ofs: offset within the first chip that the first read should start */ 591 /* ofs: offset within the first chip that the first read should start */
@@ -601,11 +609,9 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
601 chip->ref_point_counter--; 609 chip->ref_point_counter--;
602 if (chip->ref_point_counter == 0) 610 if (chip->ref_point_counter == 0)
603 chip->state = FL_READY; 611 chip->state = FL_READY;
604 } else { 612 } else
605 printk(KERN_WARNING "%s: Warning: unpoint called on non" 613 printk(KERN_WARNING "%s: Warning: unpoint called on non"
606 "pointed region\n", map->name); 614 "pointed region\n", map->name);
607 err = -EINVAL;
608 }
609 615
610 put_chip(map, chip); 616 put_chip(map, chip);
611 mutex_unlock(&chip->mutex); 617 mutex_unlock(&chip->mutex);
@@ -614,8 +620,6 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
614 ofs = 0; 620 ofs = 0;
615 chipnum++; 621 chipnum++;
616 } 622 }
617
618 return err;
619} 623}
620 624
621static int lpddr_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, 625static int lpddr_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
@@ -639,11 +643,13 @@ static int lpddr_writev(struct mtd_info *mtd, const struct kvec *vecs,
639 int chipnum; 643 int chipnum;
640 unsigned long ofs, vec_seek, i; 644 unsigned long ofs, vec_seek, i;
641 int wbufsize = 1 << lpddr->qinfo->BufSizeShift; 645 int wbufsize = 1 << lpddr->qinfo->BufSizeShift;
646
642 size_t len = 0; 647 size_t len = 0;
643 648
644 for (i = 0; i < count; i++) 649 for (i = 0; i < count; i++)
645 len += vecs[i].iov_len; 650 len += vecs[i].iov_len;
646 651
652 *retlen = 0;
647 if (!len) 653 if (!len)
648 return 0; 654 return 0;
649 655
@@ -688,6 +694,9 @@ static int lpddr_erase(struct mtd_info *mtd, struct erase_info *instr)
688 ofs = instr->addr; 694 ofs = instr->addr;
689 len = instr->len; 695 len = instr->len;
690 696
697 if (ofs > mtd->size || (len + ofs) > mtd->size)
698 return -EINVAL;
699
691 while (len > 0) { 700 while (len > 0) {
692 ret = do_erase_oneblock(mtd, ofs); 701 ret = do_erase_oneblock(mtd, ofs);
693 if (ret) 702 if (ret)
diff --git a/drivers/mtd/lpddr/qinfo_probe.c b/drivers/mtd/lpddr/qinfo_probe.c
index 45abed67f1e..dbfe17baf04 100644
--- a/drivers/mtd/lpddr/qinfo_probe.c
+++ b/drivers/mtd/lpddr/qinfo_probe.c
@@ -57,7 +57,7 @@ static struct qinfo_query_info qinfo_array[] = {
57 57
58static long lpddr_get_qinforec_pos(struct map_info *map, char *id_str) 58static long lpddr_get_qinforec_pos(struct map_info *map, char *id_str)
59{ 59{
60 int qinfo_lines = ARRAY_SIZE(qinfo_array); 60 int qinfo_lines = sizeof(qinfo_array)/sizeof(struct qinfo_query_info);
61 int i; 61 int i;
62 int bankwidth = map_bankwidth(map) * 8; 62 int bankwidth = map_bankwidth(map) * 8;
63 int major, minor; 63 int major, minor;