diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/mtd/lpddr | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/mtd/lpddr')
-rw-r--r-- | drivers/mtd/lpddr/lpddr_cmds.c | 45 | ||||
-rw-r--r-- | drivers/mtd/lpddr/qinfo_probe.c | 2 |
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 | ||
32 | static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len, | 31 | static 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); | |||
40 | static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); | 39 | static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); |
41 | static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, | 40 | static 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); |
43 | static int lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len); | 42 | static void lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len); |
44 | static int get_chip(struct map_info *map, struct flchip *chip, int mode); | 43 | static int get_chip(struct map_info *map, struct flchip *chip, int mode); |
45 | static int chip_ready(struct map_info *map, struct flchip *chip, int mode); | 44 | static int chip_ready(struct map_info *map, struct flchip *chip, int mode); |
46 | static void put_chip(struct map_info *map, struct flchip *chip); | 45 | static 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 | ||
576 | static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) | 584 | static 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 | ||
621 | static int lpddr_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, | 625 | static 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 | ||
58 | static long lpddr_get_qinforec_pos(struct map_info *map, char *id_str) | 58 | static 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; |