Late MTD fixes for 3.5:
- 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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEABECAAYFAk/+eiEACgkQdwG7hYl686NzvwCglK7p8xzqxwIUx/kCWlGqPZFr 3CsAoKf9EplTp2PvTbgyEn8+Zg+pgP/Z =YwDa -----END PGP SIGNATURE----- Merge tag 'for-linus-20120712' of git://git.infradead.org/linux-mtd 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
This commit is contained in:
commit
36ec9fbfe7
|
@ -142,13 +142,14 @@ KernelVersion: 3.4
|
|||
Contact: linux-mtd@lists.infradead.org
|
||||
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.
|
||||
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue