diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-class-mtd | 17 | ||||
| -rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 10 | ||||
| -rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 37 | ||||
| -rw-r--r-- | drivers/mtd/nand/nandsim.c | 12 |
4 files changed, 46 insertions, 30 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd index db1ad7e34fc3..938ef71e2035 100644 --- a/Documentation/ABI/testing/sysfs-class-mtd +++ b/Documentation/ABI/testing/sysfs-class-mtd | |||
| @@ -142,13 +142,14 @@ KernelVersion: 3.4 | |||
| 142 | Contact: linux-mtd@lists.infradead.org | 142 | Contact: linux-mtd@lists.infradead.org |
| 143 | Description: | 143 | Description: |
| 144 | This allows the user to examine and adjust the criteria by which | 144 | This allows the user to examine and adjust the criteria by which |
| 145 | mtd returns -EUCLEAN from mtd_read(). If the maximum number of | 145 | mtd returns -EUCLEAN from mtd_read() and mtd_read_oob(). If the |
| 146 | bit errors that were corrected on any single region comprising | 146 | maximum number of bit errors that were corrected on any single |
| 147 | an ecc step (as reported by the driver) equals or exceeds this | 147 | region comprising an ecc step (as reported by the driver) equals |
| 148 | value, -EUCLEAN is returned. Otherwise, absent an error, 0 is | 148 | or exceeds this value, -EUCLEAN is returned. Otherwise, absent |
| 149 | returned. Higher layers (e.g., UBI) use this return code as an | 149 | an error, 0 is returned. Higher layers (e.g., UBI) use this |
| 150 | indication that an erase block may be degrading and should be | 150 | return code as an indication that an erase block may be |
| 151 | scrutinized as a candidate for being marked as bad. | 151 | degrading and should be scrutinized as a candidate for being |
| 152 | marked as bad. | ||
| 152 | 153 | ||
| 153 | The initial value may be specified by the flash device driver. | 154 | The initial value may be specified by the flash device driver. |
| 154 | If not, then the default value is ecc_strength. | 155 | If not, then the default value is ecc_strength. |
| @@ -167,7 +168,7 @@ Description: | |||
| 167 | block degradation, but high enough to avoid the consequences of | 168 | block degradation, but high enough to avoid the consequences of |
| 168 | a persistent return value of -EUCLEAN on devices where sticky | 169 | a persistent return value of -EUCLEAN on devices where sticky |
| 169 | bitflips occur. Note that if bitflip_threshold exceeds | 170 | bitflips occur. Note that if bitflip_threshold exceeds |
| 170 | ecc_strength, -EUCLEAN is never returned by mtd_read(). | 171 | ecc_strength, -EUCLEAN is never returned by the read operations. |
| 171 | Conversely, if bitflip_threshold is zero, -EUCLEAN is always | 172 | Conversely, if bitflip_threshold is zero, -EUCLEAN is always |
| 172 | returned, absent a hard error. | 173 | returned, absent a hard error. |
| 173 | 174 | ||
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index a05b7b444d4f..a6cad5caba78 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
| @@ -920,12 +920,12 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 920 | */ | 920 | */ |
| 921 | memset(chip->oob_poi, ~0, mtd->oobsize); | 921 | memset(chip->oob_poi, ~0, mtd->oobsize); |
| 922 | chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0]; | 922 | chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0]; |
| 923 | |||
| 924 | read_page_swap_end(this, buf, mtd->writesize, | ||
| 925 | this->payload_virt, this->payload_phys, | ||
| 926 | nfc_geo->payload_size, | ||
| 927 | payload_virt, payload_phys); | ||
| 928 | } | 923 | } |
| 924 | |||
| 925 | read_page_swap_end(this, buf, mtd->writesize, | ||
| 926 | this->payload_virt, this->payload_phys, | ||
| 927 | nfc_geo->payload_size, | ||
| 928 | payload_virt, payload_phys); | ||
| 929 | exit_nfc: | 929 | exit_nfc: |
| 930 | return ret; | 930 | return ret; |
| 931 | } | 931 | } |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index c58e6a93f445..6acc790c2fbb 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
| @@ -273,6 +273,26 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = { | |||
| 273 | 273 | ||
| 274 | static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL }; | 274 | static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL }; |
| 275 | 275 | ||
| 276 | static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) | ||
| 277 | { | ||
| 278 | int i; | ||
| 279 | u32 *t = trg; | ||
| 280 | const __iomem u32 *s = src; | ||
| 281 | |||
| 282 | for (i = 0; i < (size >> 2); i++) | ||
| 283 | *t++ = __raw_readl(s++); | ||
| 284 | } | ||
| 285 | |||
| 286 | static void memcpy32_toio(void __iomem *trg, const void *src, int size) | ||
| 287 | { | ||
| 288 | int i; | ||
| 289 | u32 __iomem *t = trg; | ||
| 290 | const u32 *s = src; | ||
| 291 | |||
| 292 | for (i = 0; i < (size >> 2); i++) | ||
| 293 | __raw_writel(*s++, t++); | ||
| 294 | } | ||
| 295 | |||
| 276 | static int check_int_v3(struct mxc_nand_host *host) | 296 | static int check_int_v3(struct mxc_nand_host *host) |
| 277 | { | 297 | { |
| 278 | uint32_t tmp; | 298 | uint32_t tmp; |
| @@ -519,7 +539,7 @@ static void send_read_id_v3(struct mxc_nand_host *host) | |||
| 519 | 539 | ||
| 520 | wait_op_done(host, true); | 540 | wait_op_done(host, true); |
| 521 | 541 | ||
| 522 | memcpy_fromio(host->data_buf, host->main_area0, 16); | 542 | memcpy32_fromio(host->data_buf, host->main_area0, 16); |
| 523 | } | 543 | } |
| 524 | 544 | ||
| 525 | /* Request the NANDFC to perform a read of the NAND device ID. */ | 545 | /* Request the NANDFC to perform a read of the NAND device ID. */ |
| @@ -535,7 +555,7 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host) | |||
| 535 | /* Wait for operation to complete */ | 555 | /* Wait for operation to complete */ |
| 536 | wait_op_done(host, true); | 556 | wait_op_done(host, true); |
| 537 | 557 | ||
| 538 | memcpy_fromio(host->data_buf, host->main_area0, 16); | 558 | memcpy32_fromio(host->data_buf, host->main_area0, 16); |
| 539 | 559 | ||
| 540 | if (this->options & NAND_BUSWIDTH_16) { | 560 | if (this->options & NAND_BUSWIDTH_16) { |
| 541 | /* compress the ID info */ | 561 | /* compress the ID info */ |
| @@ -797,16 +817,16 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom) | |||
| 797 | 817 | ||
| 798 | if (bfrom) { | 818 | if (bfrom) { |
| 799 | for (i = 0; i < n - 1; i++) | 819 | for (i = 0; i < n - 1; i++) |
| 800 | memcpy_fromio(d + i * j, s + i * t, j); | 820 | memcpy32_fromio(d + i * j, s + i * t, j); |
| 801 | 821 | ||
| 802 | /* the last section */ | 822 | /* the last section */ |
| 803 | memcpy_fromio(d + i * j, s + i * t, mtd->oobsize - i * j); | 823 | memcpy32_fromio(d + i * j, s + i * t, mtd->oobsize - i * j); |
| 804 | } else { | 824 | } else { |
| 805 | for (i = 0; i < n - 1; i++) | 825 | for (i = 0; i < n - 1; i++) |
| 806 | memcpy_toio(&s[i * t], &d[i * j], j); | 826 | memcpy32_toio(&s[i * t], &d[i * j], j); |
| 807 | 827 | ||
| 808 | /* the last section */ | 828 | /* the last section */ |
| 809 | memcpy_toio(&s[i * t], &d[i * j], mtd->oobsize - i * j); | 829 | memcpy32_toio(&s[i * t], &d[i * j], mtd->oobsize - i * j); |
| 810 | } | 830 | } |
| 811 | } | 831 | } |
| 812 | 832 | ||
| @@ -1070,7 +1090,8 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, | |||
| 1070 | 1090 | ||
| 1071 | host->devtype_data->send_page(mtd, NFC_OUTPUT); | 1091 | host->devtype_data->send_page(mtd, NFC_OUTPUT); |
| 1072 | 1092 | ||
| 1073 | memcpy_fromio(host->data_buf, host->main_area0, mtd->writesize); | 1093 | memcpy32_fromio(host->data_buf, host->main_area0, |
| 1094 | mtd->writesize); | ||
| 1074 | copy_spare(mtd, true); | 1095 | copy_spare(mtd, true); |
| 1075 | break; | 1096 | break; |
| 1076 | 1097 | ||
| @@ -1086,7 +1107,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, | |||
| 1086 | break; | 1107 | break; |
| 1087 | 1108 | ||
| 1088 | case NAND_CMD_PAGEPROG: | 1109 | case NAND_CMD_PAGEPROG: |
| 1089 | memcpy_toio(host->main_area0, host->data_buf, mtd->writesize); | 1110 | memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize); |
| 1090 | copy_spare(mtd, false); | 1111 | copy_spare(mtd, false); |
| 1091 | host->devtype_data->send_page(mtd, NFC_INPUT); | 1112 | host->devtype_data->send_page(mtd, NFC_INPUT); |
| 1092 | host->devtype_data->send_cmd(host, command, true); | 1113 | host->devtype_data->send_cmd(host, command, true); |
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 6cc8fbfabb8e..cf0cd3146817 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
| 30 | #include <linux/vmalloc.h> | 30 | #include <linux/vmalloc.h> |
| 31 | #include <asm/div64.h> | 31 | #include <linux/math64.h> |
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
| 34 | #include <linux/string.h> | 34 | #include <linux/string.h> |
| @@ -546,12 +546,6 @@ static char *get_partition_name(int i) | |||
| 546 | return kstrdup(buf, GFP_KERNEL); | 546 | return kstrdup(buf, GFP_KERNEL); |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | static uint64_t divide(uint64_t n, uint32_t d) | ||
| 550 | { | ||
| 551 | do_div(n, d); | ||
| 552 | return n; | ||
| 553 | } | ||
| 554 | |||
| 555 | /* | 549 | /* |
| 556 | * Initialize the nandsim structure. | 550 | * Initialize the nandsim structure. |
| 557 | * | 551 | * |
| @@ -580,7 +574,7 @@ static int init_nandsim(struct mtd_info *mtd) | |||
| 580 | ns->geom.oobsz = mtd->oobsize; | 574 | ns->geom.oobsz = mtd->oobsize; |
| 581 | ns->geom.secsz = mtd->erasesize; | 575 | ns->geom.secsz = mtd->erasesize; |
| 582 | ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; | 576 | ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; |
| 583 | ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz); | 577 | ns->geom.pgnum = div_u64(ns->geom.totsz, ns->geom.pgsz); |
| 584 | ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; | 578 | ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; |
| 585 | ns->geom.secshift = ffs(ns->geom.secsz) - 1; | 579 | ns->geom.secshift = ffs(ns->geom.secsz) - 1; |
| 586 | ns->geom.pgshift = chip->page_shift; | 580 | ns->geom.pgshift = chip->page_shift; |
| @@ -921,7 +915,7 @@ static int setup_wear_reporting(struct mtd_info *mtd) | |||
| 921 | 915 | ||
| 922 | if (!rptwear) | 916 | if (!rptwear) |
| 923 | return 0; | 917 | return 0; |
| 924 | wear_eb_count = divide(mtd->size, mtd->erasesize); | 918 | wear_eb_count = div_u64(mtd->size, mtd->erasesize); |
| 925 | mem = wear_eb_count * sizeof(unsigned long); | 919 | mem = wear_eb_count * sizeof(unsigned long); |
| 926 | if (mem / sizeof(unsigned long) != wear_eb_count) { | 920 | if (mem / sizeof(unsigned long) != wear_eb_count) { |
| 927 | NS_ERR("Too many erase blocks for wear reporting\n"); | 921 | NS_ERR("Too many erase blocks for wear reporting\n"); |
