diff options
Diffstat (limited to 'package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch')
-rw-r--r-- | package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch | 719 |
1 files changed, 719 insertions, 0 deletions
diff --git a/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch b/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch new file mode 100644 index 0000000000..7f446758b9 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch @@ -0,0 +1,719 @@ +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; |