diff options
| -rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0001.c | 43 | ||||
| -rw-r--r-- | drivers/mtd/devices/elm.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/nand/nand_base.c | 6 | 
3 files changed, 49 insertions, 2 deletions
| diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index e4ec355704a6..a7543ba3e190 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -52,6 +52,11 @@  /* Atmel chips */  #define AT49BV640D	0x02de  #define AT49BV640DT	0x02db +/* Sharp chips */ +#define LH28F640BFHE_PTTL90	0x00b0 +#define LH28F640BFHE_PBTL90	0x00b1 +#define LH28F640BFHE_PTTL70A	0x00b2 +#define LH28F640BFHE_PBTL70A	0x00b3  static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);  static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -258,6 +263,36 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd)  		(cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;  }; +static int is_LH28F640BF(struct cfi_private *cfi) +{ +	/* Sharp LH28F640BF Family */ +	if (cfi->mfr == CFI_MFR_SHARP && ( +	    cfi->id == LH28F640BFHE_PTTL90 || cfi->id == LH28F640BFHE_PBTL90 || +	    cfi->id == LH28F640BFHE_PTTL70A || cfi->id == LH28F640BFHE_PBTL70A)) +		return 1; +	return 0; +} + +static void fixup_LH28F640BF(struct mtd_info *mtd) +{ +	struct map_info *map = mtd->priv; +	struct cfi_private *cfi = map->fldrv_priv; +	struct cfi_pri_intelext *extp = cfi->cmdset_priv; + +	/* Reset the Partition Configuration Register on LH28F640BF +	 * to a single partition (PCR = 0x000): PCR is embedded into A0-A15. */ +	if (is_LH28F640BF(cfi)) { +		printk(KERN_INFO "Reset Partition Config. Register: 1 Partition of 4 planes\n"); +		map_write(map, CMD(0x60), 0); +		map_write(map, CMD(0x04), 0); + +		/* We have set one single partition thus +		 * Simultaneous Operations are not allowed */ +		printk(KERN_INFO "cfi_cmdset_0001: Simultaneous Operations disabled\n"); +		extp->FeatureSupport &= ~512; +	} +} +  static void fixup_use_point(struct mtd_info *mtd)  {  	struct map_info *map = mtd->priv; @@ -309,6 +344,8 @@ static struct cfi_fixup cfi_fixup_table[] = {  	{ CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct },  	{ CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb },  	{ CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock }, +	{ CFI_MFR_SHARP, CFI_ID_ANY, fixup_unlock_powerup_lock }, +	{ CFI_MFR_SHARP, CFI_ID_ANY, fixup_LH28F640BF },  	{ 0, 0, NULL }  }; @@ -1649,6 +1686,12 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,  	initial_adr = adr;  	cmd_adr = adr & ~(wbufsize-1); +	/* Sharp LH28F640BF chips need the first address for the +	 * Page Buffer Program command. See Table 5 of +	 * LH28F320BF, LH28F640BF, LH28F128BF Series (Appendix FUM00701) */ +	if (is_LH28F640BF(cfi)) +		cmd_adr = adr; +  	/* Let's determine this according to the interleave only once */  	write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0xe8) : CMD(0xe9); diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c index 7df86948e6d4..b4f61c7fc161 100644 --- a/drivers/mtd/devices/elm.c +++ b/drivers/mtd/devices/elm.c @@ -475,6 +475,7 @@ static int elm_context_save(struct elm_info *info)  					ELM_SYNDROME_FRAGMENT_1 + offset);  			regs->elm_syndrome_fragment_0[i] = elm_read_reg(info,  					ELM_SYNDROME_FRAGMENT_0 + offset); +			break;  		default:  			return -EINVAL;  		} @@ -520,6 +521,7 @@ static int elm_context_restore(struct elm_info *info)  					regs->elm_syndrome_fragment_1[i]);  			elm_write_reg(info, ELM_SYNDROME_FRAGMENT_0 + offset,  					regs->elm_syndrome_fragment_0[i]); +			break;  		default:  			return -EINVAL;  		} diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 41167e9e991e..4f3e80c68a26 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -4047,8 +4047,10 @@ int nand_scan_tail(struct mtd_info *mtd)  		ecc->layout->oobavail += ecc->layout->oobfree[i].length;  	mtd->oobavail = ecc->layout->oobavail; -	/* ECC sanity check: warn noisily if it's too weak */ -	WARN_ON(!nand_ecc_strength_good(mtd)); +	/* ECC sanity check: warn if it's too weak */ +	if (!nand_ecc_strength_good(mtd)) +		pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n", +			mtd->name);  	/*  	 * Set the number of read / write steps for one page depending on ECC | 
