diff options
Diffstat (limited to 'drivers/mtd')
| -rw-r--r-- | drivers/mtd/mtdsuper.c | 4 | ||||
| -rw-r--r-- | drivers/mtd/nand/cafe_nand.c | 2 | ||||
| -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/nand_base.c | 7 | ||||
| -rw-r--r-- | drivers/mtd/nand/nandsim.c | 12 | ||||
| -rw-r--r-- | drivers/mtd/ubi/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/mtd/ubi/cdev.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/ubi/debug.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/ubi/misc.c | 25 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 1 | ||||
| -rw-r--r-- | drivers/mtd/ubi/vmt.c | 20 | 
12 files changed, 79 insertions, 51 deletions
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c index a90bfe79916..334da5f583c 100644 --- a/drivers/mtd/mtdsuper.c +++ b/drivers/mtd/mtdsuper.c @@ -63,7 +63,7 @@ static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,  	struct super_block *sb;  	int ret; -	sb = sget(fs_type, get_sb_mtd_compare, get_sb_mtd_set, mtd); +	sb = sget(fs_type, get_sb_mtd_compare, get_sb_mtd_set, flags, mtd);  	if (IS_ERR(sb))  		goto out_error; @@ -74,8 +74,6 @@ static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,  	pr_debug("MTDSB: New superblock for device %d (\"%s\")\n",  	      mtd->index, mtd->name); -	sb->s_flags = flags; -  	ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);  	if (ret < 0) {  		deactivate_locked_super(sb); diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 41371ba1a81..f3f6cfedd69 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -102,7 +102,7 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };  static int cafe_device_ready(struct mtd_info *mtd)  {  	struct cafe_priv *cafe = mtd->priv; -	int result = !!(cafe_readl(cafe, NAND_STATUS) | 0x40000000); +	int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000);  	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);  	cafe_writel(cafe, irqs, NAND_IRQ); diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index a05b7b444d4..a6cad5caba7 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,  		 */  		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;  } diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index c58e6a93f44..6acc790c2fb 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 = {  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); diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d47586cf64c..a11253a0fca 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3501,6 +3501,13 @@ int nand_scan_tail(struct mtd_info *mtd)  	/* propagate ecc info to mtd_info */  	mtd->ecclayout = chip->ecc.layout;  	mtd->ecc_strength = chip->ecc.strength; +	/* +	 * Initialize bitflip_threshold to its default prior scan_bbt() call. +	 * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be +	 * properly set. +	 */ +	if (!mtd->bitflip_threshold) +		mtd->bitflip_threshold = mtd->ecc_strength;  	/* Check, if we should skip the bad block table scan */  	if (chip->options & NAND_SKIP_BBTSCAN) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 6cc8fbfabb8..cf0cd314681 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -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"); diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index 738ee8dc16c..ea4b95b5451 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -29,7 +29,7 @@ config MTD_UBI_WL_THRESHOLD  config MTD_UBI_BEB_RESERVE  	int "Percentage of reserved eraseblocks for bad eraseblocks handling" -	default 1 +	default 2  	range 0 25  	help  	  If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index acec85deb6a..fb556787818 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1026,7 +1026,7 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,  	{  		int ubi_num; -		dbg_gen("dettach MTD device"); +		dbg_gen("detach MTD device");  		err = get_user(ubi_num, (__user int32_t *)argp);  		if (err) {  			err = -EFAULT; diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 09d4f8d9d59..7c138030521 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -264,7 +264,7 @@ static struct dentry *dfs_rootdir;   */  int ubi_debugfs_init(void)  { -	if (!IS_ENABLED(DEBUG_FS)) +	if (!IS_ENABLED(CONFIG_DEBUG_FS))  		return 0;  	dfs_rootdir = debugfs_create_dir("ubi", NULL); @@ -284,7 +284,7 @@ int ubi_debugfs_init(void)   */  void ubi_debugfs_exit(void)  { -	if (IS_ENABLED(DEBUG_FS)) +	if (IS_ENABLED(CONFIG_DEBUG_FS))  		debugfs_remove(dfs_rootdir);  } @@ -407,7 +407,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)  	struct dentry *dent;  	struct ubi_debug_info *d = ubi->dbg; -	if (!IS_ENABLED(DEBUG_FS)) +	if (!IS_ENABLED(CONFIG_DEBUG_FS))  		return 0;  	n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, @@ -477,6 +477,6 @@ out:   */  void ubi_debugfs_exit_dev(struct ubi_device *ubi)  { -	if (IS_ENABLED(DEBUG_FS)) +	if (IS_ENABLED(CONFIG_DEBUG_FS))  		debugfs_remove_recursive(ubi->dbg->dfs_dir);  } diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index f6a7d7ac4b9..8bbfb444b89 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c @@ -92,7 +92,30 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)  }  /** - * ubi_calculate_rsvd_pool - calculate how many PEBs must be reserved for bad + * ubi_update_reserved - update bad eraseblock handling accounting data. + * @ubi: UBI device description object + * + * This function calculates the gap between current number of PEBs reserved for + * bad eraseblock handling and the required level of PEBs that must be + * reserved, and if necessary, reserves more PEBs to fill that gap, according + * to availability. Should be called with ubi->volumes_lock held. + */ +void ubi_update_reserved(struct ubi_device *ubi) +{ +	int need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; + +	if (need <= 0 || ubi->avail_pebs == 0) +		return; + +	need = min_t(int, need, ubi->avail_pebs); +	ubi->avail_pebs -= need; +	ubi->rsvd_pebs += need; +	ubi->beb_rsvd_pebs += need; +	ubi_msg("reserved more %d PEBs for bad PEB handling", need); +} + +/** + * ubi_calculate_reserved - calculate how many PEBs must be reserved for bad   * eraseblock handling.   * @ubi: UBI device description object   */ diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index a1a81c9ea8c..84f66e3fa05 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -647,6 +647,7 @@ int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol,  int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf,  		      int length);  int ubi_check_volume(struct ubi_device *ubi, int vol_id); +void ubi_update_reserved(struct ubi_device *ubi);  void ubi_calculate_reserved(struct ubi_device *ubi);  int ubi_check_pattern(const void *buf, uint8_t patt, int size); diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 0669cff8ac3..9169e58c262 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -443,15 +443,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)  	spin_lock(&ubi->volumes_lock);  	ubi->rsvd_pebs -= reserved_pebs;  	ubi->avail_pebs += reserved_pebs; -	i = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; -	if (i > 0) { -		i = ubi->avail_pebs >= i ? i : ubi->avail_pebs; -		ubi->avail_pebs -= i; -		ubi->rsvd_pebs += i; -		ubi->beb_rsvd_pebs += i; -		if (i > 0) -			ubi_msg("reserve more %d PEBs", i); -	} +	ubi_update_reserved(ubi);  	ubi->vol_count -= 1;  	spin_unlock(&ubi->volumes_lock); @@ -558,15 +550,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)  		spin_lock(&ubi->volumes_lock);  		ubi->rsvd_pebs += pebs;  		ubi->avail_pebs -= pebs; -		pebs = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; -		if (pebs > 0) { -			pebs = ubi->avail_pebs >= pebs ? pebs : ubi->avail_pebs; -			ubi->avail_pebs -= pebs; -			ubi->rsvd_pebs += pebs; -			ubi->beb_rsvd_pebs += pebs; -			if (pebs > 0) -				ubi_msg("reserve more %d PEBs", pebs); -		} +		ubi_update_reserved(ubi);  		for (i = 0; i < reserved_pebs; i++)  			new_mapping[i] = vol->eba_tbl[i];  		kfree(vol->eba_tbl);  |