diff options
Diffstat (limited to 'drivers/mtd/chips')
| -rw-r--r-- | drivers/mtd/chips/Kconfig | 16 | ||||
| -rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0001.c | 83 | ||||
| -rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0002.c | 9 | ||||
| -rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0020.c | 7 | ||||
| -rw-r--r-- | drivers/mtd/chips/cfi_probe.c | 4 | ||||
| -rw-r--r-- | drivers/mtd/chips/cfi_util.c | 6 | ||||
| -rw-r--r-- | drivers/mtd/chips/gen_probe.c | 2 | 
7 files changed, 73 insertions, 54 deletions
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index e4696b37f3d..9f02c28c020 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -169,33 +169,33 @@ config MTD_OTP  	  in the programming of OTP bits will waste them.  config MTD_CFI_INTELEXT -	tristate "Support for Intel/Sharp flash chips" +	tristate "Support for CFI command set 0001 (Intel/Sharp chips)"  	depends on MTD_GEN_PROBE  	select MTD_CFI_UTIL  	help  	  The Common Flash Interface defines a number of different command  	  sets which a CFI-compliant chip may claim to implement. This code -	  provides support for one of those command sets, used on Intel -	  StrataFlash and other parts. +	  provides support for command set 0001, used on Intel StrataFlash +	  and other parts.  config MTD_CFI_AMDSTD -	tristate "Support for AMD/Fujitsu/Spansion flash chips" +	tristate "Support for CFI command set 0002 (AMD/Fujitsu/Spansion chips)"  	depends on MTD_GEN_PROBE  	select MTD_CFI_UTIL  	help  	  The Common Flash Interface defines a number of different command  	  sets which a CFI-compliant chip may claim to implement. This code -	  provides support for one of those command sets, used on chips -	  including the AMD Am29LV320. +	  provides support for command set 0002, used on chips including +	  the AMD Am29LV320.  config MTD_CFI_STAA -	tristate "Support for ST (Advanced Architecture) flash chips" +	tristate "Support for CFI command set 0020 (ST (Advanced Architecture) chips)"  	depends on MTD_GEN_PROBE  	select MTD_CFI_UTIL  	help  	  The Common Flash Interface defines a number of different command  	  sets which a CFI-compliant chip may claim to implement. This code -	  provides support for one of those command sets. +	  provides support for command set 0020.  config MTD_CFI_UTIL  	tristate diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 77514430f1f..a7543ba3e19 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -21,7 +21,6 @@  #include <linux/types.h>  #include <linux/kernel.h>  #include <linux/sched.h> -#include <linux/init.h>  #include <asm/io.h>  #include <asm/byteorder.h> @@ -53,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 *); @@ -69,10 +73,10 @@ static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, s  static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);  static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);  static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t); -static int cfi_intelext_get_fact_prot_info (struct mtd_info *, -					    struct otp_info *, size_t); -static int cfi_intelext_get_user_prot_info (struct mtd_info *, -					    struct otp_info *, size_t); +static int cfi_intelext_get_fact_prot_info(struct mtd_info *, size_t, +					   size_t *, struct otp_info *); +static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t, +					   size_t *, struct otp_info *);  #endif  static int cfi_intelext_suspend (struct mtd_info *);  static void cfi_intelext_resume (struct mtd_info *); @@ -259,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; @@ -310,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 }  }; @@ -435,10 +471,8 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)  	int i;  	mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); -	if (!mtd) { -		printk(KERN_ERR "Failed to allocate memory for MTD device\n"); +	if (!mtd)  		return NULL; -	}  	mtd->priv = map;  	mtd->type = MTD_NORFLASH; @@ -564,10 +598,8 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)  	mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;  	mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)  			* mtd->numeraseregions, GFP_KERNEL); -	if (!mtd->eraseregions) { -		printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); +	if (!mtd->eraseregions)  		goto setup_err; -	}  	for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {  		unsigned long ernum, ersize; @@ -1654,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); @@ -2399,24 +2437,19 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,  				     NULL, do_otp_lock, 1);  } -static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, -					   struct otp_info *buf, size_t len) -{ -	size_t retlen; -	int ret; +static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, size_t len, +					   size_t *retlen, struct otp_info *buf) -	ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 0); -	return ret ? : retlen; +{ +	return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf, +				     NULL, 0);  } -static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, -					   struct otp_info *buf, size_t len) +static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, size_t len, +					   size_t *retlen, struct otp_info *buf)  { -	size_t retlen; -	int ret; - -	ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 1); -	return ret ? : retlen; +	return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf, +				     NULL, 1);  }  #endif diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 89b9d689153..e21fde9d4d7 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -24,7 +24,6 @@  #include <linux/types.h>  #include <linux/kernel.h>  #include <linux/sched.h> -#include <linux/init.h>  #include <asm/io.h>  #include <asm/byteorder.h> @@ -507,10 +506,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)  	int i;  	mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); -	if (!mtd) { -		printk(KERN_WARNING "Failed to allocate memory for MTD device\n"); +	if (!mtd)  		return NULL; -	}  	mtd->priv = map;  	mtd->type = MTD_NORFLASH; @@ -661,10 +658,8 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)  	mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;  	mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)  				    * mtd->numeraseregions, GFP_KERNEL); -	if (!mtd->eraseregions) { -		printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); +	if (!mtd->eraseregions)  		goto setup_err; -	}  	for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {  		unsigned long ernum, ersize; diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 096993f9711..423666b51ef 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -22,7 +22,6 @@  #include <linux/types.h>  #include <linux/kernel.h>  #include <linux/sched.h> -#include <linux/init.h>  #include <asm/io.h>  #include <asm/byteorder.h> @@ -176,7 +175,6 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)  	//printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips);  	if (!mtd) { -		printk(KERN_ERR "Failed to allocate memory for MTD device\n");  		kfree(cfi->cmdset_priv);  		return NULL;  	} @@ -189,7 +187,6 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)  	mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)  			* mtd->numeraseregions, GFP_KERNEL);  	if (!mtd->eraseregions) { -		printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");  		kfree(cfi->cmdset_priv);  		kfree(mtd);  		return NULL; @@ -964,7 +961,7 @@ static int cfi_staa_erase_varsize(struct mtd_info *mtd,  			chipnum++;  			if (chipnum >= cfi->numchips) -			break; +				break;  		}  	} @@ -1173,7 +1170,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)  			chipnum++;  			if (chipnum >= cfi->numchips) -			break; +				break;  		}  	}  	return 0; diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index d2553527940..e8d0164498b 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c @@ -168,10 +168,8 @@ static int __xipram cfi_chip_setup(struct map_info *map,  		return 0;  	cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); -	if (!cfi->cfiq) { -		printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); +	if (!cfi->cfiq)  		return 0; -	}  	memset(cfi->cfiq,0,sizeof(struct cfi_ident)); diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index f992418f40a..09c79bd0b4f 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -116,10 +116,8 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n  	printk(KERN_INFO "%s Extended Query Table at 0x%4.4X\n", name, adr);  	extp = kmalloc(size, GFP_KERNEL); -	if (!extp) { -		printk(KERN_ERR "Failed to allocate memory\n"); +	if (!extp)  		goto out; -	}  #ifdef CONFIG_MTD_XIP  	local_irq_disable(); @@ -241,7 +239,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,  			chipnum++;  			if (chipnum >= cfi->numchips) -			break; +				break;  		}  	} diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c index ffb36ba8a6e..b57ceea2151 100644 --- a/drivers/mtd/chips/gen_probe.c +++ b/drivers/mtd/chips/gen_probe.c @@ -114,7 +114,6 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi  	mapsize = sizeof(long) * DIV_ROUND_UP(max_chips, BITS_PER_LONG);  	chip_map = kzalloc(mapsize, GFP_KERNEL);  	if (!chip_map) { -		printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);  		kfree(cfi.cfiq);  		return NULL;  	} @@ -139,7 +138,6 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi  	retcfi = kmalloc(sizeof(struct cfi_private) + cfi.numchips * sizeof(struct flchip), GFP_KERNEL);  	if (!retcfi) { -		printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name);  		kfree(cfi.cfiq);  		kfree(chip_map);  		return NULL;  | 
