Skip to content

Commit

Permalink
Merge tag 'for-linus-20120712' of git://git.infradead.org/linux-mtd
Browse files Browse the repository at this point in the history
Pull late MTD fixes from David Woodhouse:
 - fix 'sparse warning fix' regression which totally breaks MXC NAND
 - fix GPMI NAND regression when used with UBI
 - update/correct sysfs documentation for new 'bitflip_threshold' field
 - fix nandsim build failure

* tag 'for-linus-20120712' of git://git.infradead.org/linux-mtd:
  mtd: nandsim: don't open code a do_div helper
  mtd: ABI documentation: clarification of bitflip_threshold
  mtd: gpmi-nand: fix read page when reading to vmalloced area
  mtd: mxc_nand: use 32bit copy functions
  • Loading branch information
torvalds committed Jul 13, 2012
2 parents 7801dc3 + 596fd46 commit 36ec9fb
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 30 deletions.
17 changes: 9 additions & 8 deletions Documentation/ABI/testing/sysfs-class-mtd
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,14 @@ KernelVersion: 3.4
Contact: [email protected]
Description:
This allows the user to examine and adjust the criteria by which
mtd returns -EUCLEAN from mtd_read(). If the maximum number of
bit errors that were corrected on any single region comprising
an ecc step (as reported by the driver) equals or exceeds this
value, -EUCLEAN is returned. Otherwise, absent an error, 0 is
returned. Higher layers (e.g., UBI) use this return code as an
indication that an erase block may be degrading and should be
scrutinized as a candidate for being marked as bad.
mtd returns -EUCLEAN from mtd_read() and mtd_read_oob(). If the
maximum number of bit errors that were corrected on any single
region comprising an ecc step (as reported by the driver) equals
or exceeds this value, -EUCLEAN is returned. Otherwise, absent
an error, 0 is returned. Higher layers (e.g., UBI) use this
return code as an indication that an erase block may be
degrading and should be scrutinized as a candidate for being
marked as bad.

The initial value may be specified by the flash device driver.
If not, then the default value is ecc_strength.
Expand All @@ -167,7 +168,7 @@ Description:
block degradation, but high enough to avoid the consequences of
a persistent return value of -EUCLEAN on devices where sticky
bitflips occur. Note that if bitflip_threshold exceeds
ecc_strength, -EUCLEAN is never returned by mtd_read().
ecc_strength, -EUCLEAN is never returned by the read operations.
Conversely, if bitflip_threshold is zero, -EUCLEAN is always
returned, absent a hard error.

Expand Down
10 changes: 5 additions & 5 deletions drivers/mtd/nand/gpmi-nand/gpmi-nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,12 +920,12 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
*/
memset(chip->oob_poi, ~0, mtd->oobsize);
chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];

read_page_swap_end(this, buf, mtd->writesize,
this->payload_virt, this->payload_phys,
nfc_geo->payload_size,
payload_virt, payload_phys);
}

read_page_swap_end(this, buf, mtd->writesize,
this->payload_virt, this->payload_phys,
nfc_geo->payload_size,
payload_virt, payload_phys);
exit_nfc:
return ret;
}
Expand Down
37 changes: 29 additions & 8 deletions drivers/mtd/nand/mxc_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,26 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = {

static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL };

static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size)
{
int i;
u32 *t = trg;
const __iomem u32 *s = src;

for (i = 0; i < (size >> 2); i++)
*t++ = __raw_readl(s++);
}

static void memcpy32_toio(void __iomem *trg, const void *src, int size)
{
int i;
u32 __iomem *t = trg;
const u32 *s = src;

for (i = 0; i < (size >> 2); i++)
__raw_writel(*s++, t++);
}

static int check_int_v3(struct mxc_nand_host *host)
{
uint32_t tmp;
Expand Down Expand Up @@ -519,7 +539,7 @@ static void send_read_id_v3(struct mxc_nand_host *host)

wait_op_done(host, true);

memcpy_fromio(host->data_buf, host->main_area0, 16);
memcpy32_fromio(host->data_buf, host->main_area0, 16);
}

/* Request the NANDFC to perform a read of the NAND device ID. */
Expand All @@ -535,7 +555,7 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host)
/* Wait for operation to complete */
wait_op_done(host, true);

memcpy_fromio(host->data_buf, host->main_area0, 16);
memcpy32_fromio(host->data_buf, host->main_area0, 16);

if (this->options & NAND_BUSWIDTH_16) {
/* compress the ID info */
Expand Down Expand Up @@ -797,16 +817,16 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)

if (bfrom) {
for (i = 0; i < n - 1; i++)
memcpy_fromio(d + i * j, s + i * t, j);
memcpy32_fromio(d + i * j, s + i * t, j);

/* the last section */
memcpy_fromio(d + i * j, s + i * t, mtd->oobsize - i * j);
memcpy32_fromio(d + i * j, s + i * t, mtd->oobsize - i * j);
} else {
for (i = 0; i < n - 1; i++)
memcpy_toio(&s[i * t], &d[i * j], j);
memcpy32_toio(&s[i * t], &d[i * j], j);

/* the last section */
memcpy_toio(&s[i * t], &d[i * j], mtd->oobsize - i * j);
memcpy32_toio(&s[i * t], &d[i * j], mtd->oobsize - i * j);
}
}

Expand Down Expand Up @@ -1070,7 +1090,8 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,

host->devtype_data->send_page(mtd, NFC_OUTPUT);

memcpy_fromio(host->data_buf, host->main_area0, mtd->writesize);
memcpy32_fromio(host->data_buf, host->main_area0,
mtd->writesize);
copy_spare(mtd, true);
break;

Expand All @@ -1086,7 +1107,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
break;

case NAND_CMD_PAGEPROG:
memcpy_toio(host->main_area0, host->data_buf, mtd->writesize);
memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize);
copy_spare(mtd, false);
host->devtype_data->send_page(mtd, NFC_INPUT);
host->devtype_data->send_cmd(host, command, true);
Expand Down
12 changes: 3 additions & 9 deletions drivers/mtd/nand/nandsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <asm/div64.h>
#include <linux/math64.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/string.h>
Expand Down Expand Up @@ -546,12 +546,6 @@ static char *get_partition_name(int i)
return kstrdup(buf, GFP_KERNEL);
}

static uint64_t divide(uint64_t n, uint32_t d)
{
do_div(n, d);
return n;
}

/*
* Initialize the nandsim structure.
*
Expand Down Expand Up @@ -580,7 +574,7 @@ static int init_nandsim(struct mtd_info *mtd)
ns->geom.oobsz = mtd->oobsize;
ns->geom.secsz = mtd->erasesize;
ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz;
ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz);
ns->geom.pgnum = div_u64(ns->geom.totsz, ns->geom.pgsz);
ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz;
ns->geom.secshift = ffs(ns->geom.secsz) - 1;
ns->geom.pgshift = chip->page_shift;
Expand Down Expand Up @@ -921,7 +915,7 @@ static int setup_wear_reporting(struct mtd_info *mtd)

if (!rptwear)
return 0;
wear_eb_count = divide(mtd->size, mtd->erasesize);
wear_eb_count = div_u64(mtd->size, mtd->erasesize);
mem = wear_eb_count * sizeof(unsigned long);
if (mem / sizeof(unsigned long) != wear_eb_count) {
NS_ERR("Too many erase blocks for wear reporting\n");
Expand Down

0 comments on commit 36ec9fb

Please sign in to comment.