mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 17:01:14 +00:00
720 lines
21 KiB
Diff
720 lines
21 KiB
Diff
|
From 73d127565b5a4b19bcaacabc505689ee039f16fd Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
|
||
|
Date: Sun, 11 Nov 2012 03:11:38 +0100
|
||
|
Subject: sf: factor out malloc from SPI flash drivers
|
||
|
|
||
|
Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
|
||
|
|
||
|
--- a/drivers/mtd/spi/atmel.c
|
||
|
+++ b/drivers/mtd/spi/atmel.c
|
||
|
@@ -40,18 +40,6 @@ struct atmel_spi_flash_params {
|
||
|
const char *name;
|
||
|
};
|
||
|
|
||
|
-/* spi_flash needs to be first so upper layers can free() it */
|
||
|
-struct atmel_spi_flash {
|
||
|
- struct spi_flash flash;
|
||
|
- const struct atmel_spi_flash_params *params;
|
||
|
-};
|
||
|
-
|
||
|
-static inline struct atmel_spi_flash *
|
||
|
-to_atmel_spi_flash(struct spi_flash *flash)
|
||
|
-{
|
||
|
- return container_of(flash, struct atmel_spi_flash, flash);
|
||
|
-}
|
||
|
-
|
||
|
static const struct atmel_spi_flash_params atmel_spi_flash_table[] = {
|
||
|
{
|
||
|
.idcode1 = 0x22,
|
||
|
@@ -156,7 +144,8 @@ static int at45_wait_ready(struct spi_fl
|
||
|
* Assemble the address part of a command for AT45 devices in
|
||
|
* non-power-of-two page size mode.
|
||
|
*/
|
||
|
-static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset)
|
||
|
+static void at45_build_address(const struct atmel_spi_flash_params *params,
|
||
|
+ u8 *cmd, u32 offset)
|
||
|
{
|
||
|
unsigned long page_addr;
|
||
|
unsigned long byte_addr;
|
||
|
@@ -167,7 +156,7 @@ static void at45_build_address(struct at
|
||
|
* The "extra" space per page is the power-of-two page size
|
||
|
* divided by 32.
|
||
|
*/
|
||
|
- page_shift = asf->params->l2_page_size;
|
||
|
+ page_shift = params->l2_page_size;
|
||
|
page_size = (1 << page_shift) + (1 << (page_shift - 5));
|
||
|
page_shift++;
|
||
|
page_addr = offset / page_size;
|
||
|
@@ -181,11 +170,11 @@ static void at45_build_address(struct at
|
||
|
static int dataflash_read_fast_at45(struct spi_flash *flash,
|
||
|
u32 offset, size_t len, void *buf)
|
||
|
{
|
||
|
- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
|
||
|
+ const struct atmel_spi_flash_params *params = flash->priv;
|
||
|
u8 cmd[5];
|
||
|
|
||
|
cmd[0] = CMD_READ_ARRAY_FAST;
|
||
|
- at45_build_address(asf, cmd + 1, offset);
|
||
|
+ at45_build_address(params, cmd + 1, offset);
|
||
|
cmd[4] = 0x00;
|
||
|
|
||
|
return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
|
||
|
@@ -197,7 +186,7 @@ static int dataflash_read_fast_at45(stru
|
||
|
static int dataflash_write_p2(struct spi_flash *flash,
|
||
|
u32 offset, size_t len, const void *buf)
|
||
|
{
|
||
|
- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
|
||
|
+ const struct atmel_spi_flash_params *params = flash->priv;
|
||
|
unsigned long page_size;
|
||
|
u32 addr = offset;
|
||
|
size_t chunk_len;
|
||
|
@@ -211,7 +200,7 @@ static int dataflash_write_p2(struct spi
|
||
|
* the other is being programmed into main memory.
|
||
|
*/
|
||
|
|
||
|
- page_size = (1 << asf->params->l2_page_size);
|
||
|
+ page_size = (1 << params->l2_page_size);
|
||
|
|
||
|
ret = spi_claim_bus(flash->spi);
|
||
|
if (ret) {
|
||
|
@@ -263,7 +252,7 @@ out:
|
||
|
static int dataflash_write_at45(struct spi_flash *flash,
|
||
|
u32 offset, size_t len, const void *buf)
|
||
|
{
|
||
|
- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
|
||
|
+ const struct atmel_spi_flash_params *params = flash->priv;
|
||
|
unsigned long page_addr;
|
||
|
unsigned long byte_addr;
|
||
|
unsigned long page_size;
|
||
|
@@ -279,7 +268,7 @@ static int dataflash_write_at45(struct s
|
||
|
* the other is being programmed into main memory.
|
||
|
*/
|
||
|
|
||
|
- page_shift = asf->params->l2_page_size;
|
||
|
+ page_shift = params->l2_page_size;
|
||
|
page_size = (1 << page_shift) + (1 << (page_shift - 5));
|
||
|
page_shift++;
|
||
|
page_addr = offset / page_size;
|
||
|
@@ -338,7 +327,7 @@ out:
|
||
|
*/
|
||
|
static int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len)
|
||
|
{
|
||
|
- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
|
||
|
+ const struct atmel_spi_flash_params *params = flash->priv;
|
||
|
unsigned long page_size;
|
||
|
|
||
|
size_t actual;
|
||
|
@@ -351,7 +340,7 @@ static int dataflash_erase_p2(struct spi
|
||
|
* when possible.
|
||
|
*/
|
||
|
|
||
|
- page_size = (1 << asf->params->l2_page_size);
|
||
|
+ page_size = (1 << params->l2_page_size);
|
||
|
|
||
|
if (offset % page_size || len % page_size) {
|
||
|
debug("SF: Erase offset/length not multiple of page size\n");
|
||
|
@@ -397,7 +386,7 @@ out:
|
||
|
|
||
|
static int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len)
|
||
|
{
|
||
|
- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
|
||
|
+ const struct atmel_spi_flash_params *params = flash->priv;
|
||
|
unsigned long page_addr;
|
||
|
unsigned long page_size;
|
||
|
unsigned int page_shift;
|
||
|
@@ -411,7 +400,7 @@ static int dataflash_erase_at45(struct s
|
||
|
* when possible.
|
||
|
*/
|
||
|
|
||
|
- page_shift = asf->params->l2_page_size;
|
||
|
+ page_shift = params->l2_page_size;
|
||
|
page_size = (1 << page_shift) + (1 << (page_shift - 5));
|
||
|
page_shift++;
|
||
|
page_addr = offset / page_size;
|
||
|
@@ -458,12 +447,12 @@ out:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
|
||
|
+int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode)
|
||
|
{
|
||
|
const struct atmel_spi_flash_params *params;
|
||
|
+ struct spi_slave *spi = flash->spi;
|
||
|
unsigned page_size;
|
||
|
unsigned int family;
|
||
|
- struct atmel_spi_flash *asf;
|
||
|
unsigned int i;
|
||
|
int ret;
|
||
|
u8 status;
|
||
|
@@ -477,18 +466,11 @@ struct spi_flash *spi_flash_probe_atmel(
|
||
|
if (i == ARRAY_SIZE(atmel_spi_flash_table)) {
|
||
|
debug("SF: Unsupported DataFlash ID %02x\n",
|
||
|
idcode[1]);
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- asf = malloc(sizeof(struct atmel_spi_flash));
|
||
|
- if (!asf) {
|
||
|
- debug("SF: Failed to allocate memory\n");
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
- asf->params = params;
|
||
|
- asf->flash.spi = spi;
|
||
|
- asf->flash.name = params->name;
|
||
|
+ flash->priv = (void *)params;
|
||
|
+ flash->name = params->name;
|
||
|
|
||
|
/* Assuming power-of-two page size initially. */
|
||
|
page_size = 1 << params->l2_page_size;
|
||
|
@@ -503,48 +485,44 @@ struct spi_flash *spi_flash_probe_atmel(
|
||
|
*/
|
||
|
ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1);
|
||
|
if (ret)
|
||
|
- goto err;
|
||
|
+ return -1;
|
||
|
|
||
|
debug("SF: AT45 status register: %02x\n", status);
|
||
|
|
||
|
if (!(status & AT45_STATUS_P2_PAGE_SIZE)) {
|
||
|
- asf->flash.read = dataflash_read_fast_at45;
|
||
|
- asf->flash.write = dataflash_write_at45;
|
||
|
- asf->flash.erase = dataflash_erase_at45;
|
||
|
+ flash->read = dataflash_read_fast_at45;
|
||
|
+ flash->write = dataflash_write_at45;
|
||
|
+ 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;
|
||
|
+ flash->read = spi_flash_cmd_read_fast;
|
||
|
+ flash->write = dataflash_write_p2;
|
||
|
+ flash->erase = dataflash_erase_p2;
|
||
|
}
|
||
|
|
||
|
- asf->flash.page_size = page_size;
|
||
|
- asf->flash.sector_size = page_size;
|
||
|
+ flash->page_size = page_size;
|
||
|
+ flash->sector_size = page_size;
|
||
|
break;
|
||
|
|
||
|
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;
|
||
|
+ flash->read = spi_flash_cmd_read_fast;
|
||
|
+ flash->write = spi_flash_cmd_write_multi;
|
||
|
+ flash->erase = spi_flash_cmd_erase;
|
||
|
+ flash->page_size = page_size;
|
||
|
+ flash->sector_size = 4096;
|
||
|
/* clear SPRL# bit for locked flash */
|
||
|
- spi_flash_cmd_write_status(&asf->flash, 0);
|
||
|
+ spi_flash_cmd_write_status(flash, 0);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
debug("SF: Unsupported DataFlash family %u\n", family);
|
||
|
- goto err;
|
||
|
+ return -1;
|
||
|
}
|
||
|
|
||
|
- asf->flash.size = page_size * params->pages_per_block
|
||
|
+ flash->size = page_size * params->pages_per_block
|
||
|
* params->blocks_per_sector
|
||
|
* params->nr_sectors;
|
||
|
|
||
|
- return &asf->flash;
|
||
|
-
|
||
|
-err:
|
||
|
- free(asf);
|
||
|
- return NULL;
|
||
|
+ return 1;
|
||
|
}
|
||
|
--- a/drivers/mtd/spi/eon.c
|
||
|
+++ b/drivers/mtd/spi/eon.c
|
||
|
@@ -29,10 +29,9 @@ static const struct eon_spi_flash_params
|
||
|
},
|
||
|
};
|
||
|
|
||
|
-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
|
||
|
+int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode)
|
||
|
{
|
||
|
const struct eon_spi_flash_params *params;
|
||
|
- struct spi_flash *flash;
|
||
|
unsigned int i;
|
||
|
|
||
|
for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) {
|
||
|
@@ -43,16 +42,10 @@ struct spi_flash *spi_flash_probe_eon(st
|
||
|
|
||
|
if (i == ARRAY_SIZE(eon_spi_flash_table)) {
|
||
|
debug("SF: Unsupported EON ID %02x\n", idcode[1]);
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
- flash = malloc(sizeof(*flash));
|
||
|
- if (!flash) {
|
||
|
- debug("SF: Failed to allocate memory\n");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- flash->spi = spi;
|
||
|
+ flash->priv = (void *)params;
|
||
|
flash->name = params->name;
|
||
|
|
||
|
flash->write = spi_flash_cmd_write_multi;
|
||
|
@@ -63,5 +56,5 @@ struct spi_flash *spi_flash_probe_eon(st
|
||
|
flash->size = 256 * 16
|
||
|
* params->nr_sectors;
|
||
|
|
||
|
- return flash;
|
||
|
+ return 1;
|
||
|
}
|
||
|
--- a/drivers/mtd/spi/macronix.c
|
||
|
+++ b/drivers/mtd/spi/macronix.c
|
||
|
@@ -79,10 +79,9 @@ static const struct macronix_spi_flash_p
|
||
|
},
|
||
|
};
|
||
|
|
||
|
-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
|
||
|
+int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode)
|
||
|
{
|
||
|
const struct macronix_spi_flash_params *params;
|
||
|
- struct spi_flash *flash;
|
||
|
unsigned int i;
|
||
|
u16 id = idcode[2] | idcode[1] << 8;
|
||
|
|
||
|
@@ -94,16 +93,10 @@ struct spi_flash *spi_flash_probe_macron
|
||
|
|
||
|
if (i == ARRAY_SIZE(macronix_spi_flash_table)) {
|
||
|
debug("SF: Unsupported Macronix ID %04x\n", id);
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
- flash = malloc(sizeof(*flash));
|
||
|
- if (!flash) {
|
||
|
- debug("SF: Failed to allocate memory\n");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- flash->spi = spi;
|
||
|
+ flash->priv = (void *)params;
|
||
|
flash->name = params->name;
|
||
|
|
||
|
flash->write = spi_flash_cmd_write_multi;
|
||
|
@@ -116,5 +109,5 @@ struct spi_flash *spi_flash_probe_macron
|
||
|
/* Clear BP# bits for read-only flash */
|
||
|
spi_flash_cmd_write_status(flash, 0);
|
||
|
|
||
|
- return flash;
|
||
|
+ return 1;
|
||
|
}
|
||
|
--- a/drivers/mtd/spi/ramtron.c
|
||
|
+++ b/drivers/mtd/spi/ramtron.c
|
||
|
@@ -69,17 +69,6 @@ struct ramtron_spi_fram_params {
|
||
|
const char *name; /* name for display and/or matching */
|
||
|
};
|
||
|
|
||
|
-struct ramtron_spi_fram {
|
||
|
- struct spi_flash flash;
|
||
|
- const struct ramtron_spi_fram_params *params;
|
||
|
-};
|
||
|
-
|
||
|
-static inline struct ramtron_spi_fram *to_ramtron_spi_fram(struct spi_flash
|
||
|
- *flash)
|
||
|
-{
|
||
|
- return container_of(flash, struct ramtron_spi_fram, flash);
|
||
|
-}
|
||
|
-
|
||
|
/*
|
||
|
* table describing supported FRAM chips:
|
||
|
* chips without RDID command must have the values 0xff for id1 and id2
|
||
|
@@ -155,18 +144,18 @@ static const struct ramtron_spi_fram_par
|
||
|
static int ramtron_common(struct spi_flash *flash,
|
||
|
u32 offset, size_t len, void *buf, u8 command)
|
||
|
{
|
||
|
- struct ramtron_spi_fram *sn = to_ramtron_spi_fram(flash);
|
||
|
+ const struct ramtron_spi_fram_params *params = flash->priv;
|
||
|
u8 cmd[4];
|
||
|
int cmd_len;
|
||
|
int ret;
|
||
|
|
||
|
- if (sn->params->addr_len == 3 && sn->params->merge_cmd == 0) {
|
||
|
+ if (params->addr_len == 3 && params->merge_cmd == 0) {
|
||
|
cmd[0] = command;
|
||
|
cmd[1] = offset >> 16;
|
||
|
cmd[2] = offset >> 8;
|
||
|
cmd[3] = offset;
|
||
|
cmd_len = 4;
|
||
|
- } else if (sn->params->addr_len == 2 && sn->params->merge_cmd == 0) {
|
||
|
+ } else if (params->addr_len == 2 && params->merge_cmd == 0) {
|
||
|
cmd[0] = command;
|
||
|
cmd[1] = offset >> 8;
|
||
|
cmd[2] = offset;
|
||
|
@@ -230,10 +219,9 @@ static int ramtron_erase(struct spi_flas
|
||
|
* nore: we are called here with idcode pointing to the first non-0x7f byte
|
||
|
* already!
|
||
|
*/
|
||
|
-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
|
||
|
+int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode)
|
||
|
{
|
||
|
const struct ramtron_spi_fram_params *params;
|
||
|
- struct ramtron_spi_fram *sn;
|
||
|
unsigned int i;
|
||
|
#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
|
||
|
int ret;
|
||
|
@@ -259,11 +247,11 @@ struct spi_flash *spi_fram_probe_ramtron
|
||
|
*/
|
||
|
ret = spi_flash_cmd(spi, CMD_READ_STATUS, &sr, 1);
|
||
|
if (ret)
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
|
||
|
/* Bits 5,4,0 are fixed 0 for all devices */
|
||
|
if ((sr & 0x31) != 0x00)
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
/* now find the device */
|
||
|
for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
|
||
|
params = &ramtron_spi_fram_table[i];
|
||
|
@@ -281,23 +269,16 @@ struct spi_flash *spi_fram_probe_ramtron
|
||
|
/* arriving here means no method has found a device we can handle */
|
||
|
debug("SF/ramtron: unsupported device id0=%02x id1=%02x id2=%02x\n",
|
||
|
idcode[0], idcode[1], idcode[2]);
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
|
||
|
found:
|
||
|
- sn = malloc(sizeof(*sn));
|
||
|
- if (!sn) {
|
||
|
- debug("SF: Failed to allocate memory\n");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
+ flash->priv = (void *)params;
|
||
|
+ flash->name = params->name;
|
||
|
|
||
|
- sn->params = params;
|
||
|
- sn->flash.spi = spi;
|
||
|
- sn->flash.name = params->name;
|
||
|
-
|
||
|
- sn->flash.write = ramtron_write;
|
||
|
- sn->flash.read = ramtron_read;
|
||
|
- sn->flash.erase = ramtron_erase;
|
||
|
- sn->flash.size = params->size;
|
||
|
+ flash->write = ramtron_write;
|
||
|
+ flash->read = ramtron_read;
|
||
|
+ flash->erase = ramtron_erase;
|
||
|
+ flash->size = params->size;
|
||
|
|
||
|
- return &sn->flash;
|
||
|
+ return 1;
|
||
|
}
|
||
|
--- a/drivers/mtd/spi/spansion.c
|
||
|
+++ b/drivers/mtd/spi/spansion.c
|
||
|
@@ -105,10 +105,9 @@ static const struct spansion_spi_flash_p
|
||
|
},
|
||
|
};
|
||
|
|
||
|
-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
|
||
|
+int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode)
|
||
|
{
|
||
|
const struct spansion_spi_flash_params *params;
|
||
|
- struct spi_flash *flash;
|
||
|
unsigned int i;
|
||
|
unsigned short jedec, ext_jedec;
|
||
|
|
||
|
@@ -125,16 +124,10 @@ struct spi_flash *spi_flash_probe_spansi
|
||
|
|
||
|
if (i == ARRAY_SIZE(spansion_spi_flash_table)) {
|
||
|
debug("SF: Unsupported SPANSION ID %04x %04x\n", jedec, ext_jedec);
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
- flash = malloc(sizeof(*flash));
|
||
|
- if (!flash) {
|
||
|
- debug("SF: Failed to allocate memory\n");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- flash->spi = spi;
|
||
|
+ flash->priv = (void *)params;
|
||
|
flash->name = params->name;
|
||
|
|
||
|
flash->write = spi_flash_cmd_write_multi;
|
||
|
@@ -144,5 +137,5 @@ struct spi_flash *spi_flash_probe_spansi
|
||
|
flash->sector_size = 256 * params->pages_per_sector;
|
||
|
flash->size = flash->sector_size * params->nr_sectors;
|
||
|
|
||
|
- return flash;
|
||
|
+ return 1;
|
||
|
}
|
||
|
--- a/drivers/mtd/spi/spi_flash.c
|
||
|
+++ b/drivers/mtd/spi/spi_flash.c
|
||
|
@@ -296,7 +296,7 @@ int spi_flash_cmd_write_status(struct sp
|
||
|
static struct {
|
||
|
const u8 shift;
|
||
|
const u8 idcode;
|
||
|
- struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
|
||
|
+ int (*probe) (struct spi_flash *flash, u8 *idcode);
|
||
|
} flashes[] = {
|
||
|
/* Keep it sorted by define name */
|
||
|
#ifdef CONFIG_SPI_FLASH_ATMEL
|
||
|
@@ -343,7 +343,7 @@ struct spi_flash *spi_flash_probe(unsign
|
||
|
unsigned int max_hz, unsigned int spi_mode)
|
||
|
{
|
||
|
struct spi_slave *spi;
|
||
|
- struct spi_flash *flash = NULL;
|
||
|
+ struct spi_flash *flash;
|
||
|
int ret, i, shift;
|
||
|
u8 idcode[IDCODE_LEN], *idp;
|
||
|
#ifdef CONFIG_NEEDS_MANUAL_RELOC
|
||
|
@@ -379,6 +379,15 @@ struct spi_flash *spi_flash_probe(unsign
|
||
|
print_buffer(0, idcode, 1, sizeof(idcode), 0);
|
||
|
#endif
|
||
|
|
||
|
+ flash = malloc(sizeof(*flash));
|
||
|
+ if (!flash) {
|
||
|
+ debug("SF: failed to alloc memory\n");
|
||
|
+ goto err_malloc;
|
||
|
+ }
|
||
|
+
|
||
|
+ memset(flash, 0, sizeof(*flash));
|
||
|
+ flash->spi = spi;
|
||
|
+
|
||
|
/* count the number of continuation bytes */
|
||
|
for (shift = 0, idp = idcode;
|
||
|
shift < IDCODE_CONT_LEN && *idp == 0x7f;
|
||
|
@@ -389,12 +398,12 @@ struct spi_flash *spi_flash_probe(unsign
|
||
|
for (i = 0; i < ARRAY_SIZE(flashes); ++i)
|
||
|
if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
|
||
|
/* we have a match, call probe */
|
||
|
- flash = flashes[i].probe(spi, idp);
|
||
|
- if (flash)
|
||
|
+ ret = flashes[i].probe(flash, idp);
|
||
|
+ if (ret)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
- if (!flash) {
|
||
|
+ if (ret <= 0) {
|
||
|
printf("SF: Unsupported manufacturer %02x\n", *idp);
|
||
|
goto err_manufacturer_probe;
|
||
|
}
|
||
|
@@ -408,6 +417,8 @@ struct spi_flash *spi_flash_probe(unsign
|
||
|
return flash;
|
||
|
|
||
|
err_manufacturer_probe:
|
||
|
+ free(flash);
|
||
|
+err_malloc:
|
||
|
err_read_id:
|
||
|
spi_release_bus(spi);
|
||
|
err_claim_bus:
|
||
|
--- a/drivers/mtd/spi/spi_flash_internal.h
|
||
|
+++ b/drivers/mtd/spi/spi_flash_internal.h
|
||
|
@@ -98,11 +98,11 @@ int spi_flash_cmd_wait_ready(struct spi_
|
||
|
int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len);
|
||
|
|
||
|
/* Manufacturer-specific probe functions */
|
||
|
-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode);
|
||
|
-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode);
|
||
|
-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode);
|
||
|
-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode);
|
||
|
-struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode);
|
||
|
-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode);
|
||
|
-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode);
|
||
|
-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode);
|
||
|
+int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode);
|
||
|
+int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode);
|
||
|
+int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode);
|
||
|
+int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode);
|
||
|
+int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode);
|
||
|
+int spi_flash_probe_stmicro(struct spi_flash *flash, u8 *idcode);
|
||
|
+int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode);
|
||
|
+int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode);
|
||
|
--- a/drivers/mtd/spi/sst.c
|
||
|
+++ b/drivers/mtd/spi/sst.c
|
||
|
@@ -39,11 +39,6 @@ struct sst_spi_flash_params {
|
||
|
const char *name;
|
||
|
};
|
||
|
|
||
|
-struct sst_spi_flash {
|
||
|
- struct spi_flash flash;
|
||
|
- const struct sst_spi_flash_params *params;
|
||
|
-};
|
||
|
-
|
||
|
static const struct sst_spi_flash_params sst_spi_flash_table[] = {
|
||
|
{
|
||
|
.idcode1 = 0x8d,
|
||
|
@@ -185,11 +180,9 @@ sst_write_wp(struct spi_flash *flash, u3
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
-struct spi_flash *
|
||
|
-spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)
|
||
|
+int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode)
|
||
|
{
|
||
|
const struct sst_spi_flash_params *params;
|
||
|
- struct sst_spi_flash *stm;
|
||
|
size_t i;
|
||
|
|
||
|
for (i = 0; i < ARRAY_SIZE(sst_spi_flash_table); ++i) {
|
||
|
@@ -200,31 +193,24 @@ spi_flash_probe_sst(struct spi_slave *sp
|
||
|
|
||
|
if (i == ARRAY_SIZE(sst_spi_flash_table)) {
|
||
|
debug("SF: Unsupported SST ID %02x\n", idcode[1]);
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- stm = malloc(sizeof(*stm));
|
||
|
- if (!stm) {
|
||
|
- debug("SF: Failed to allocate memory\n");
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
- stm->params = params;
|
||
|
- stm->flash.spi = spi;
|
||
|
- stm->flash.name = params->name;
|
||
|
+ flash->priv = (void *)params;
|
||
|
+ flash->name = params->name;
|
||
|
|
||
|
- if (stm->params->flags & SST_FEAT_WP)
|
||
|
- stm->flash.write = sst_write_wp;
|
||
|
+ if (params->flags & SST_FEAT_WP)
|
||
|
+ 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;
|
||
|
+ 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 = flash->sector_size * params->nr_sectors;
|
||
|
|
||
|
/* Flash powers up read-only, so clear BP# bits */
|
||
|
- spi_flash_cmd_write_status(&stm->flash, 0);
|
||
|
+ spi_flash_cmd_write_status(flash, 0);
|
||
|
|
||
|
- return &stm->flash;
|
||
|
+ return 1;
|
||
|
}
|
||
|
--- a/drivers/mtd/spi/stmicro.c
|
||
|
+++ b/drivers/mtd/spi/stmicro.c
|
||
|
@@ -112,10 +112,10 @@ static const struct stmicro_spi_flash_pa
|
||
|
},
|
||
|
};
|
||
|
|
||
|
-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
|
||
|
+int spi_flash_probe_stmicro(struct spi_flash *flash, u8 * idcode)
|
||
|
{
|
||
|
const struct stmicro_spi_flash_params *params;
|
||
|
- struct spi_flash *flash;
|
||
|
+ struct spi_slave *spi = flash->spi;
|
||
|
unsigned int i;
|
||
|
u16 id;
|
||
|
|
||
|
@@ -123,13 +123,13 @@ struct spi_flash *spi_flash_probe_stmicr
|
||
|
i = spi_flash_cmd(spi, CMD_M25PXX_RES,
|
||
|
idcode, 4);
|
||
|
if (i)
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
if ((idcode[3] & 0xf0) == 0x10) {
|
||
|
idcode[0] = 0x20;
|
||
|
idcode[1] = 0x20;
|
||
|
idcode[2] = idcode[3] + 1;
|
||
|
} else
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
id = ((idcode[1] << 8) | idcode[2]);
|
||
|
@@ -143,16 +143,10 @@ struct spi_flash *spi_flash_probe_stmicr
|
||
|
|
||
|
if (i == ARRAY_SIZE(stmicro_spi_flash_table)) {
|
||
|
debug("SF: Unsupported STMicro ID %04x\n", id);
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
- flash = malloc(sizeof(*flash));
|
||
|
- if (!flash) {
|
||
|
- debug("SF: Failed to allocate memory\n");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- flash->spi = spi;
|
||
|
+ flash->priv = (void *)params;
|
||
|
flash->name = params->name;
|
||
|
|
||
|
flash->write = spi_flash_cmd_write_multi;
|
||
|
@@ -162,5 +156,5 @@ struct spi_flash *spi_flash_probe_stmicr
|
||
|
flash->sector_size = 256 * params->pages_per_sector;
|
||
|
flash->size = flash->sector_size * params->nr_sectors;
|
||
|
|
||
|
- return flash;
|
||
|
+ return 1;
|
||
|
}
|
||
|
--- a/drivers/mtd/spi/winbond.c
|
||
|
+++ b/drivers/mtd/spi/winbond.c
|
||
|
@@ -69,10 +69,9 @@ static const struct winbond_spi_flash_pa
|
||
|
},
|
||
|
};
|
||
|
|
||
|
-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
|
||
|
+int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode)
|
||
|
{
|
||
|
const struct winbond_spi_flash_params *params;
|
||
|
- struct spi_flash *flash;
|
||
|
unsigned int i;
|
||
|
|
||
|
for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
|
||
|
@@ -84,16 +83,10 @@ struct spi_flash *spi_flash_probe_winbon
|
||
|
if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
|
||
|
debug("SF: Unsupported Winbond ID %02x%02x\n",
|
||
|
idcode[1], idcode[2]);
|
||
|
- return NULL;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
- flash = malloc(sizeof(*flash));
|
||
|
- if (!flash) {
|
||
|
- debug("SF: Failed to allocate memory\n");
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- flash->spi = spi;
|
||
|
+ flash->priv = (void *)params;
|
||
|
flash->name = params->name;
|
||
|
|
||
|
flash->write = spi_flash_cmd_write_multi;
|
||
|
@@ -103,5 +96,5 @@ struct spi_flash *spi_flash_probe_winbon
|
||
|
flash->sector_size = 4096;
|
||
|
flash->size = 4096 * 16 * params->nr_blocks;
|
||
|
|
||
|
- return flash;
|
||
|
+ return 1;
|
||
|
}
|
||
|
--- a/include/spi_flash.h
|
||
|
+++ b/include/spi_flash.h
|
||
|
@@ -31,6 +31,7 @@ struct spi_flash {
|
||
|
struct spi_slave *spi;
|
||
|
|
||
|
const char *name;
|
||
|
+ void *priv;
|
||
|
|
||
|
/* Total flash size */
|
||
|
u32 size;
|