aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-class-mtd17
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c10
-rw-r--r--drivers/mtd/nand/mxc_nand.c37
-rw-r--r--drivers/mtd/nand/nandsim.c12
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
142Contact: linux-mtd@lists.infradead.org 142Contact: linux-mtd@lists.infradead.org
143Description: 143Description:
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);
929exit_nfc: 929exit_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
274static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL }; 274static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL };
275 275
276static 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
286static 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
276static int check_int_v3(struct mxc_nand_host *host) 296static 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
549static 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");