diff options
Diffstat (limited to 'drivers/mtd')
| -rw-r--r-- | drivers/mtd/spi/atmel.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/spi/eon.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/spi/macronix.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/spi/ramtron.c | 4 | ||||
| -rw-r--r-- | drivers/mtd/spi/spansion.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/spi/spi_flash.c | 81 | ||||
| -rw-r--r-- | drivers/mtd/spi/sst.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/spi/stmicro.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/spi/winbond.c | 8 | 
9 files changed, 86 insertions, 55 deletions
diff --git a/drivers/mtd/spi/atmel.c b/drivers/mtd/spi/atmel.c index 006f6d5d0..6a92c4b77 100644 --- a/drivers/mtd/spi/atmel.c +++ b/drivers/mtd/spi/atmel.c @@ -480,15 +480,13 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)  		return NULL;  	} -	asf = malloc(sizeof(struct atmel_spi_flash)); +	asf = spi_flash_alloc(struct atmel_spi_flash, spi, params->name);  	if (!asf) {  		debug("SF: Failed to allocate memory\n");  		return NULL;  	}  	asf->params = params; -	asf->flash.spi = spi; -	asf->flash.name = params->name;  	/* Assuming power-of-two page size initially. */  	page_size = 1 << params->l2_page_size; @@ -513,7 +511,6 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)  			asf->flash.erase = dataflash_erase_at45;  			page_size += 1 << (params->l2_page_size - 5);  		} else { -			asf->flash.read = spi_flash_cmd_read_fast;  			asf->flash.write = dataflash_write_p2;  			asf->flash.erase = dataflash_erase_p2;  		} @@ -524,9 +521,6 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)  	case DF_FAMILY_AT26F:  	case DF_FAMILY_AT26DF: -		asf->flash.read = spi_flash_cmd_read_fast; -		asf->flash.write = spi_flash_cmd_write_multi; -		asf->flash.erase = spi_flash_cmd_erase;  		asf->flash.page_size = page_size;  		asf->flash.sector_size = 4096;  		/* clear SPRL# bit for locked flash */ diff --git a/drivers/mtd/spi/eon.c b/drivers/mtd/spi/eon.c index 691ed4efc..b16e7ab09 100644 --- a/drivers/mtd/spi/eon.c +++ b/drivers/mtd/spi/eon.c @@ -46,18 +46,12 @@ struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)  		return NULL;  	} -	flash = malloc(sizeof(*flash)); +	flash = spi_flash_alloc_base(spi, params->name);  	if (!flash) {  		debug("SF: Failed to allocate memory\n");  		return NULL;  	} -	flash->spi = spi; -	flash->name = params->name; - -	flash->write = spi_flash_cmd_write_multi; -	flash->erase = spi_flash_cmd_erase; -	flash->read = spi_flash_cmd_read_fast;  	flash->page_size = 256;  	flash->sector_size = 256 * 16 * 16;  	flash->size = 256 * 16 diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c index c97a39d49..036c30d3b 100644 --- a/drivers/mtd/spi/macronix.c +++ b/drivers/mtd/spi/macronix.c @@ -97,18 +97,12 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)  		return NULL;  	} -	flash = malloc(sizeof(*flash)); +	flash = spi_flash_alloc_base(spi, params->name);  	if (!flash) {  		debug("SF: Failed to allocate memory\n");  		return NULL;  	} -	flash->spi = spi; -	flash->name = params->name; - -	flash->write = spi_flash_cmd_write_multi; -	flash->erase = spi_flash_cmd_erase; -	flash->read = spi_flash_cmd_read_fast;  	flash->page_size = 256;  	flash->sector_size = 256 * 16 * 16;  	flash->size = flash->sector_size * params->nr_blocks; diff --git a/drivers/mtd/spi/ramtron.c b/drivers/mtd/spi/ramtron.c index 099978149..5299a6dbd 100644 --- a/drivers/mtd/spi/ramtron.c +++ b/drivers/mtd/spi/ramtron.c @@ -284,15 +284,13 @@ struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)  	return NULL;  found: -	sn = malloc(sizeof(*sn)); +	sn = spi_flash_alloc(struct ramtron_spi_fram, spi, params->name);  	if (!sn) {  		debug("SF: Failed to allocate memory\n");  		return NULL;  	}  	sn->params = params; -	sn->flash.spi = spi; -	sn->flash.name = params->name;  	sn->flash.write = ramtron_write;  	sn->flash.read = ramtron_read; diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c index 9288672c8..bc558c4c9 100644 --- a/drivers/mtd/spi/spansion.c +++ b/drivers/mtd/spi/spansion.c @@ -128,18 +128,12 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)  		return NULL;  	} -	flash = malloc(sizeof(*flash)); +	flash = spi_flash_alloc_base(spi, params->name);  	if (!flash) {  		debug("SF: Failed to allocate memory\n");  		return NULL;  	} -	flash->spi = spi; -	flash->name = params->name; - -	flash->write = spi_flash_cmd_write_multi; -	flash->erase = spi_flash_cmd_erase; -	flash->read = spi_flash_cmd_read_fast;  	flash->page_size = 256;  	flash->sector_size = 256 * params->pages_per_sector;  	flash->size = flash->sector_size * params->nr_sectors; diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 00aece929..111185af1 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -8,6 +8,7 @@   */  #include <common.h> +#include <fdtdec.h>  #include <malloc.h>  #include <spi.h>  #include <spi_flash.h> @@ -15,6 +16,8 @@  #include "spi_flash_internal.h" +DECLARE_GLOBAL_DATA_PTR; +  static void spi_flash_addr(u32 addr, u8 *cmd)  {  	/* cmd[0] is actual command */ @@ -87,6 +90,9 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,  	for (actual = 0; actual < len; actual += chunk_len) {  		chunk_len = min(len - actual, page_size - byte_addr); +		if (flash->spi->max_write_size) +			chunk_len = min(chunk_len, flash->spi->max_write_size); +  		cmd[1] = page_addr >> 8;  		cmd[2] = page_addr;  		cmd[3] = byte_addr; @@ -111,8 +117,11 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,  		if (ret)  			break; -		page_addr++; -		byte_addr = 0; +		byte_addr += chunk_len; +		if (byte_addr == page_size) { +			page_addr++; +			byte_addr = 0; +		}  	}  	debug("SF: program %s %zu bytes @ %#x\n", @@ -140,6 +149,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,  {  	u8 cmd[5]; +	/* Handle memory-mapped SPI */ +	if (flash->memory_map) +		memcpy(data, flash->memory_map + offset, len); +  	cmd[0] = CMD_READ_ARRAY_FAST;  	spi_flash_addr(offset, cmd);  	cmd[4] = 0x00; @@ -269,6 +282,34 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)  	return 0;  } +#ifdef CONFIG_OF_CONTROL +int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) +{ +	fdt_addr_t addr; +	fdt_size_t size; +	int node; + +	/* If there is no node, do nothing */ +	node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); +	if (node < 0) +		return 0; + +	addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); +	if (addr == FDT_ADDR_T_NONE) { +		debug("%s: Cannot decode address\n", __func__); +		return 0; +	} + +	if (flash->size != size) { +		debug("%s: Memory map must cover entire device\n", __func__); +		return -1; +	} +	flash->memory_map = (void *)addr; + +	return 0; +} +#endif /* CONFIG_OF_CONTROL */ +  /*   * The following table holds all device probe functions   * @@ -385,9 +426,18 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,  		goto err_manufacturer_probe;  	} +#ifdef CONFIG_OF_CONTROL +	if (spi_flash_decode_fdt(gd->fdt_blob, flash)) { +		debug("SF: FDT decode error\n"); +		goto err_manufacturer_probe; +	} +#endif  	printf("SF: Detected %s with page size ", flash->name);  	print_size(flash->sector_size, ", total "); -	print_size(flash->size, "\n"); +	print_size(flash->size, ""); +	if (flash->memory_map) +		printf(", mapped at %p", flash->memory_map); +	puts("\n");  	spi_release_bus(spi); @@ -401,6 +451,31 @@ err_claim_bus:  	return NULL;  } +void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi, +			 const char *name) +{ +	struct spi_flash *flash; +	void *ptr; + +	ptr = malloc(size); +	if (!ptr) { +		debug("SF: Failed to allocate memory\n"); +		return NULL; +	} +	memset(ptr, '\0', size); +	flash = (struct spi_flash *)(ptr + offset); + +	/* Set up some basic fields - caller will sort out sizes */ +	flash->spi = spi; +	flash->name = name; + +	flash->read = spi_flash_cmd_read_fast; +	flash->write = spi_flash_cmd_write_multi; +	flash->erase = spi_flash_cmd_erase; + +	return flash; +} +  void spi_flash_free(struct spi_flash *flash)  {  	spi_free_slave(flash->spi); diff --git a/drivers/mtd/spi/sst.c b/drivers/mtd/spi/sst.c index ced4f2473..95f5490c3 100644 --- a/drivers/mtd/spi/sst.c +++ b/drivers/mtd/spi/sst.c @@ -203,22 +203,16 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)  		return NULL;  	} -	stm = malloc(sizeof(*stm)); +	stm = spi_flash_alloc(struct sst_spi_flash, spi, params->name);  	if (!stm) {  		debug("SF: Failed to allocate memory\n");  		return NULL;  	}  	stm->params = params; -	stm->flash.spi = spi; -	stm->flash.name = params->name;  	if (stm->params->flags & SST_FEAT_WP)  		stm->flash.write = sst_write_wp; -	else -		stm->flash.write = spi_flash_cmd_write_multi; -	stm->flash.erase = spi_flash_cmd_erase; -	stm->flash.read = spi_flash_cmd_read_fast;  	stm->flash.page_size = 256;  	stm->flash.sector_size = 4096;  	stm->flash.size = stm->flash.sector_size * params->nr_sectors; diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c index 8a193449d..2a9972bd4 100644 --- a/drivers/mtd/spi/stmicro.c +++ b/drivers/mtd/spi/stmicro.c @@ -176,18 +176,12 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)  		return NULL;  	} -	flash = malloc(sizeof(*flash)); +	flash = spi_flash_alloc_base(spi, params->name);  	if (!flash) {  		debug("SF: Failed to allocate memory\n");  		return NULL;  	} -	flash->spi = spi; -	flash->name = params->name; - -	flash->write = spi_flash_cmd_write_multi; -	flash->erase = spi_flash_cmd_erase; -	flash->read = spi_flash_cmd_read_fast;  	flash->page_size = 256;  	flash->sector_size = 256 * params->pages_per_sector;  	flash->size = flash->sector_size * params->nr_sectors; diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c index 441830216..05dc64492 100644 --- a/drivers/mtd/spi/winbond.c +++ b/drivers/mtd/spi/winbond.c @@ -92,18 +92,12 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)  		return NULL;  	} -	flash = malloc(sizeof(*flash)); +	flash = spi_flash_alloc_base(spi, params->name);  	if (!flash) {  		debug("SF: Failed to allocate memory\n");  		return NULL;  	} -	flash->spi = spi; -	flash->name = params->name; - -	flash->write = spi_flash_cmd_write_multi; -	flash->erase = spi_flash_cmd_erase; -	flash->read = spi_flash_cmd_read_fast;  	flash->page_size = 256;  	flash->sector_size = 4096;  	flash->size = 4096 * 16 * params->nr_blocks;  |