diff options
45 files changed, 406 insertions, 332 deletions
diff --git a/src/cpu/amd/pi/spi.c b/src/cpu/amd/pi/spi.c index f5718057d1..71b5d95444 100644 --- a/src/cpu/amd/pi/spi.c +++ b/src/cpu/amd/pi/spi.c @@ -31,15 +31,13 @@ void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len) return; } - flash->spi->rw = SPI_WRITE_FLAG; - spi_claim_bus(flash->spi); + spi_flash_volatile_group_begin(flash); - flash->erase(flash, pos, size); - flash->write(flash, pos, sizeof(len), &len); - flash->write(flash, pos + sizeof(len), len, buf); + spi_flash_erase(flash, pos, size); + spi_flash_write(flash, pos, sizeof(len), &len); + spi_flash_write(flash, pos + sizeof(len), len, buf); - flash->spi->rw = SPI_WRITE_FLAG; - spi_release_bus(flash->spi); + spi_flash_volatile_group_end(flash); return; } diff --git a/src/drivers/intel/fsp1_0/fastboot_cache.c b/src/drivers/intel/fsp1_0/fastboot_cache.c index 68150f9379..b57f382b27 100644 --- a/src/drivers/intel/fsp1_0/fastboot_cache.c +++ b/src/drivers/intel/fsp1_0/fastboot_cache.c @@ -209,16 +209,16 @@ void update_mrc_cache(void *unused) "Need to erase the MRC cache region of %d bytes at %p\n", cache_size, cache_base); - flash->erase(flash, to_flash_offset(cache_base), cache_size); + spi_flash_erase(flash, to_flash_offset(cache_base), cache_size); /* we will start at the beginning again */ cache = cache_base; } - /* 4. write mrc data with flash->write() */ + /* 4. write mrc data with spi_flash_write() */ printk(BIOS_DEBUG, "Write MRC cache update to flash at %p\n", cache); - flash->write(flash, to_flash_offset(cache), - current->mrc_data_size + sizeof(*current), current); + spi_flash_write(flash, to_flash_offset(cache), + current->mrc_data_size + sizeof(*current), current); } #endif /* !defined(__PRE_RAM__) */ diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig index 4c2fd1f060..b55de58962 100644 --- a/src/drivers/spi/Kconfig +++ b/src/drivers/spi/Kconfig @@ -164,6 +164,13 @@ config SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B output command (opcode 0x3b) where the opcode and address are sent to the chip on MOSI and data is received on both MOSI and MISO. +config SPI_FLASH_HAS_VOLATILE_GROUP + bool + default n + help + Allows chipset to group write/erase operations under a single volatile + group. + endif # SPI_FLASH config HAVE_SPI_CONSOLE_SUPPORT diff --git a/src/drivers/spi/adesto.c b/src/drivers/spi/adesto.c index fdde90f697..91bb774e36 100644 --- a/src/drivers/spi/adesto.c +++ b/src/drivers/spi/adesto.c @@ -10,8 +10,10 @@ * Licensed under the GPL-2 or later. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -46,7 +48,7 @@ struct adesto_spi_flash { }; static inline struct adesto_spi_flash * -to_adesto_spi_flash(struct spi_flash *flash) +to_adesto_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct adesto_spi_flash, flash); } @@ -78,8 +80,8 @@ static const struct adesto_spi_flash_params adesto_spi_flash_table[] = { }, }; -static int adesto_write(struct spi_flash *flash, - u32 offset, size_t len, const void *buf) +static int adesto_write(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) { struct adesto_spi_flash *stm = to_adesto_spi_flash(flash); unsigned long byte_addr; @@ -92,13 +94,6 @@ static int adesto_write(struct spi_flash *flash, page_size = 1 << stm->params->l2_page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - ret = spi_claim_bus(flash->spi); - if (ret) { - printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); - return ret; - } - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); @@ -141,7 +136,6 @@ static int adesto_write(struct spi_flash *flash, ret = 0; out: - spi_release_bus(flash->spi); return ret; } @@ -177,12 +171,12 @@ struct spi_flash *spi_flash_probe_adesto(struct spi_slave *spi, u8 *idcode) /* Assuming power-of-two page size initially. */ page_size = 1 << params->l2_page_size; - stm->flash.write = adesto_write; - stm->flash.erase = spi_flash_cmd_erase; + stm->flash.internal_write = adesto_write; + stm->flash.internal_erase = spi_flash_cmd_erase; #if CONFIG_SPI_FLASH_NO_FAST_READ - stm->flash.read = spi_flash_cmd_read_slow; + stm->flash.internal_read = spi_flash_cmd_read_slow; #else - stm->flash.read = spi_flash_cmd_read_fast; + stm->flash.internal_read = spi_flash_cmd_read_fast; #endif stm->flash.sector_size = (1 << stm->params->l2_page_size) * stm->params->pages_per_sector; diff --git a/src/drivers/spi/amic.c b/src/drivers/spi/amic.c index e5f6672002..4f3002c73b 100644 --- a/src/drivers/spi/amic.c +++ b/src/drivers/spi/amic.c @@ -8,8 +8,10 @@ * Licensed under the GPL-2 or later. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -44,7 +46,7 @@ struct amic_spi_flash { }; static inline struct amic_spi_flash * -to_amic_spi_flash(struct spi_flash *flash) +to_amic_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct amic_spi_flash, flash); } @@ -60,8 +62,8 @@ static const struct amic_spi_flash_params amic_spi_flash_table[] = { }, }; -static int amic_write(struct spi_flash *flash, - u32 offset, size_t len, const void *buf) +static int amic_write(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) { struct amic_spi_flash *amic = to_amic_spi_flash(flash); unsigned long byte_addr; @@ -74,13 +76,6 @@ static int amic_write(struct spi_flash *flash, page_size = 1 << amic->params->l2_page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - ret = spi_claim_bus(flash->spi); - if (ret) { - printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); - return ret; - } - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); @@ -123,7 +118,6 @@ static int amic_write(struct spi_flash *flash, ret = 0; out: - spi_release_bus(flash->spi); return ret; } @@ -159,12 +153,12 @@ struct spi_flash *spi_flash_probe_amic(struct spi_slave *spi, u8 *idcode) /* Assuming power-of-two page size initially. */ page_size = 1 << params->l2_page_size; - amic->flash.write = amic_write; - amic->flash.erase = spi_flash_cmd_erase; + amic->flash.internal_write = amic_write; + amic->flash.internal_erase = spi_flash_cmd_erase; #if CONFIG_SPI_FLASH_NO_FAST_READ - amic->flash.read = spi_flash_cmd_read_slow; + amic->flash.internal_read = spi_flash_cmd_read_slow; #else - amic->flash.read = spi_flash_cmd_read_fast; + amic->flash.internal_read = spi_flash_cmd_read_fast; #endif amic->flash.sector_size = (1 << amic->params->l2_page_size) * amic->params->pages_per_sector; diff --git a/src/drivers/spi/atmel.c b/src/drivers/spi/atmel.c index 0286e09cdc..e53889205d 100644 --- a/src/drivers/spi/atmel.c +++ b/src/drivers/spi/atmel.c @@ -6,8 +6,10 @@ * Licensed under the GPL-2 or later. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" /* M25Pxx-specific commands */ @@ -41,7 +43,7 @@ struct atmel_spi_flash { }; static inline struct atmel_spi_flash * -to_atmel_spi_flash(struct spi_flash *flash) +to_atmel_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct atmel_spi_flash, flash); } @@ -105,8 +107,8 @@ static const struct atmel_spi_flash_params atmel_spi_flash_table[] = { }, }; -static int atmel_write(struct spi_flash *flash, - u32 offset, size_t len, const void *buf) +static int atmel_write(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) { struct atmel_spi_flash *stm = to_atmel_spi_flash(flash); unsigned long byte_addr; @@ -119,13 +121,6 @@ static int atmel_write(struct spi_flash *flash, page_size = 1 << stm->params->l2_page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - ret = spi_claim_bus(flash->spi); - if (ret) { - printk(BIOS_WARNING, "SF: Unable to claim SPI bus\n"); - return ret; - } - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); @@ -168,7 +163,6 @@ static int atmel_write(struct spi_flash *flash, ret = 0; out: - spi_release_bus(flash->spi); return ret; } @@ -204,12 +198,12 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) /* Assuming power-of-two page size initially. */ page_size = 1 << params->l2_page_size; - stm->flash.write = atmel_write; - stm->flash.erase = spi_flash_cmd_erase; + stm->flash.internal_write = atmel_write; + stm->flash.internal_erase = spi_flash_cmd_erase; #if CONFIG_SPI_FLASH_NO_FAST_READ - stm->flash.read = spi_flash_cmd_read_slow; + stm->flash.internal_read = spi_flash_cmd_read_slow; #else - stm->flash.read = spi_flash_cmd_read_fast; + stm->flash.internal_read = spi_flash_cmd_read_fast; #endif stm->flash.sector_size = (1 << stm->params->l2_page_size) * stm->params->pages_per_sector; diff --git a/src/drivers/spi/boot_device_rw_nommap.c b/src/drivers/spi/boot_device_rw_nommap.c index 32ded9c393..a52a7befd2 100644 --- a/src/drivers/spi/boot_device_rw_nommap.c +++ b/src/drivers/spi/boot_device_rw_nommap.c @@ -16,6 +16,7 @@ #include <arch/early_variables.h> #include <boot_device.h> #include <spi_flash.h> +#include <spi-generic.h> static struct spi_flash *sfg CAR_GLOBAL; @@ -27,7 +28,7 @@ static ssize_t spi_readat(const struct region_device *rd, void *b, if (sf == NULL) return -1; - if (sf->read(sf, offset, size, b)) + if (spi_flash_read(sf, offset, size, b)) return -1; return size; @@ -41,7 +42,7 @@ static ssize_t spi_writeat(const struct region_device *rd, const void *b, if (sf == NULL) return -1; - if (sf->write(sf, offset, size, b)) + if (spi_flash_write(sf, offset, size, b)) return -1; return size; @@ -55,7 +56,7 @@ static ssize_t spi_eraseat(const struct region_device *rd, if (sf == NULL) return -1; - if (sf->erase(sf, offset, size)) + if (spi_flash_erase(sf, offset, size)) return -1; return size; diff --git a/src/drivers/spi/cbfs_spi.c b/src/drivers/spi/cbfs_spi.c index 46e7346379..7aeec57cf6 100644 --- a/src/drivers/spi/cbfs_spi.c +++ b/src/drivers/spi/cbfs_spi.c @@ -20,6 +20,7 @@ */ #include <boot_device.h> +#include <console/console.h> #include <spi_flash.h> #include <symbols.h> #include <cbmem.h> @@ -46,7 +47,7 @@ static ssize_t spi_readat(const struct region_device *rd, void *b, if (show) stopwatch_init(&sw); - if (spi_flash_info->read(spi_flash_info, offset, size, b)) + if (spi_flash_read(spi_flash_info, offset, size, b)) return -1; if (show) { long usecs; @@ -67,7 +68,7 @@ static ssize_t spi_readat(const struct region_device *rd, void *b, static ssize_t spi_writeat(const struct region_device *rd, const void *b, size_t offset, size_t size) { - if (spi_flash_info->write(spi_flash_info, offset, size, b)) + if (spi_flash_write(spi_flash_info, offset, size, b)) return -1; return size; } @@ -75,7 +76,7 @@ static ssize_t spi_writeat(const struct region_device *rd, const void *b, static ssize_t spi_eraseat(const struct region_device *rd, size_t offset, size_t size) { - if (spi_flash_info->erase(spi_flash_info, offset, size)) + if (spi_flash_erase(spi_flash_info, offset, size)) return -1; return size; } diff --git a/src/drivers/spi/eon.c b/src/drivers/spi/eon.c index 923b0a5601..64307664de 100644 --- a/src/drivers/spi/eon.c +++ b/src/drivers/spi/eon.c @@ -6,8 +6,10 @@ * Licensed under the GPL-2 or later. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -43,7 +45,8 @@ struct eon_spi_flash { const struct eon_spi_flash_params *params; }; -static inline struct eon_spi_flash *to_eon_spi_flash(struct spi_flash *flash) +static inline +struct eon_spi_flash *to_eon_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct eon_spi_flash, flash); } @@ -75,7 +78,7 @@ static const struct eon_spi_flash_params eon_spi_flash_table[] = { }, }; -static int eon_write(struct spi_flash *flash, +static int eon_write(const struct spi_flash *flash, u32 offset, size_t len, const void *buf) { struct eon_spi_flash *eon = to_eon_spi_flash(flash); @@ -89,8 +92,6 @@ static int eon_write(struct spi_flash *flash, page_size = 1 << eon->params->page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); @@ -166,10 +167,10 @@ struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode) eon->flash.spi = spi; eon->flash.name = params->name; - eon->flash.write = eon_write; - eon->flash.erase = spi_flash_cmd_erase; - eon->flash.status = spi_flash_cmd_status; - eon->flash.read = spi_flash_cmd_read_fast; + eon->flash.internal_write = eon_write; + eon->flash.internal_erase = spi_flash_cmd_erase; + eon->flash.internal_status = spi_flash_cmd_status; + eon->flash.internal_read = spi_flash_cmd_read_fast; eon->flash.sector_size = params->page_size * params->pages_per_sector; eon->flash.size = params->page_size * params->pages_per_sector * params->nr_sectors; diff --git a/src/drivers/spi/gigadevice.c b/src/drivers/spi/gigadevice.c index 780cc82b23..3146a97167 100644 --- a/src/drivers/spi/gigadevice.c +++ b/src/drivers/spi/gigadevice.c @@ -17,9 +17,10 @@ * GNU General Public License for more details. */ - +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -54,7 +55,7 @@ struct gigadevice_spi_flash { }; static inline struct gigadevice_spi_flash * -to_gigadevice_spi_flash(struct spi_flash *flash) +to_gigadevice_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct gigadevice_spi_flash, flash); } @@ -118,8 +119,8 @@ static const struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] = { }, }; -static int gigadevice_write(struct spi_flash *flash, u32 offset, - size_t len, const void *buf) +static int gigadevice_write(const struct spi_flash *flash, u32 offset, + size_t len, const void *buf) { struct gigadevice_spi_flash *stm = to_gigadevice_spi_flash(flash); unsigned long byte_addr; @@ -132,8 +133,6 @@ static int gigadevice_write(struct spi_flash *flash, u32 offset, page_size = 1 << stm->params->l2_page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); @@ -212,13 +211,13 @@ struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode) /* Assuming power-of-two page size initially. */ page_size = 1 << params->l2_page_size; - stm.flash.write = gigadevice_write; - stm.flash.erase = spi_flash_cmd_erase; - stm.flash.status = spi_flash_cmd_status; + stm.flash.internal_write = gigadevice_write; + stm.flash.internal_erase = spi_flash_cmd_erase; + stm.flash.internal_status = spi_flash_cmd_status; #if CONFIG_SPI_FLASH_NO_FAST_READ - stm.flash.read = spi_flash_cmd_read_slow; + stm.flash.internal_read = spi_flash_cmd_read_slow; #else - stm.flash.read = spi_flash_cmd_read_fast; + stm.flash.internal_read = spi_flash_cmd_read_fast; #endif stm.flash.sector_size = (1 << stm.params->l2_page_size) * stm.params->pages_per_sector; diff --git a/src/drivers/spi/macronix.c b/src/drivers/spi/macronix.c index 09cb80cb0e..799cc97c8b 100644 --- a/src/drivers/spi/macronix.c +++ b/src/drivers/spi/macronix.c @@ -21,8 +21,10 @@ * GNU General Public License for more details. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -56,8 +58,8 @@ struct macronix_spi_flash { const struct macronix_spi_flash_params *params; }; -static inline struct macronix_spi_flash *to_macronix_spi_flash(struct spi_flash - *flash) +static inline +struct macronix_spi_flash *to_macronix_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct macronix_spi_flash, flash); } @@ -145,8 +147,8 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = { }, }; -static int macronix_write(struct spi_flash *flash, - u32 offset, size_t len, const void *buf) +static int macronix_write(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) { struct macronix_spi_flash *mcx = to_macronix_spi_flash(flash); unsigned long byte_addr; @@ -159,8 +161,6 @@ static int macronix_write(struct spi_flash *flash, page_size = mcx->params->page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); @@ -227,13 +227,13 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode) mcx.flash.spi = spi; mcx.flash.name = params->name; - mcx.flash.write = macronix_write; - mcx.flash.erase = spi_flash_cmd_erase; - mcx.flash.status = spi_flash_cmd_status; + mcx.flash.internal_write = macronix_write; + mcx.flash.internal_erase = spi_flash_cmd_erase; + mcx.flash.internal_status = spi_flash_cmd_status; #if CONFIG_SPI_FLASH_NO_FAST_READ - mcx.flash.read = spi_flash_cmd_read_slow; + mcx.flash.internal_read = spi_flash_cmd_read_slow; #else - mcx.flash.read = spi_flash_cmd_read_fast; + mcx.flash.internal_read = spi_flash_cmd_read_fast; #endif mcx.flash.sector_size = params->page_size * params->pages_per_sector; mcx.flash.size = mcx.flash.sector_size * params->sectors_per_block * diff --git a/src/drivers/spi/spansion.c b/src/drivers/spi/spansion.c index fc6cef99af..95b1bafe05 100644 --- a/src/drivers/spi/spansion.c +++ b/src/drivers/spi/spansion.c @@ -17,8 +17,10 @@ * GNU General Public License for more details. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -66,8 +68,8 @@ struct spansion_spi_flash { const struct spansion_spi_flash_params *params; }; -static inline struct spansion_spi_flash *to_spansion_spi_flash(struct spi_flash - *flash) +static inline +struct spansion_spi_flash *to_spansion_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct spansion_spi_flash, flash); } @@ -198,8 +200,8 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = { }, }; -static int spansion_write(struct spi_flash *flash, - u32 offset, size_t len, const void *buf) +static int spansion_write(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) { struct spansion_spi_flash *spsn = to_spansion_spi_flash(flash); unsigned long page_addr; @@ -214,8 +216,6 @@ static int spansion_write(struct spi_flash *flash, page_addr = offset / page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); @@ -286,10 +286,10 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) spsn->flash.spi = spi; spsn->flash.name = params->name; - spsn->flash.write = spansion_write; - spsn->flash.erase = spi_flash_cmd_erase; - spsn->flash.read = spi_flash_cmd_read_slow; - spsn->flash.status = spi_flash_cmd_status; + spsn->flash.internal_write = spansion_write; + spsn->flash.internal_erase = spi_flash_cmd_erase; + spsn->flash.internal_read = spi_flash_cmd_read_slow; + spsn->flash.internal_status = spi_flash_cmd_status; spsn->flash.sector_size = params->page_size * params->pages_per_sector; spsn->flash.size = spsn->flash.sector_size * params->nr_sectors; spsn->flash.erase_cmd = CMD_S25FLXX_SE; diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index 60064208d2..7ca6822ba1 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -7,6 +7,8 @@ * Licensed under the GPL-2 or later. */ +#include <arch/early_variables.h> +#include <assert.h> #include <boot_device.h> #include <cbfs.h> #include <cpu/x86/smm.h> @@ -142,8 +144,8 @@ static int spi_flash_cmd_read_array(struct spi_slave *spi, u8 *cmd, return len != 0; } -int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, - size_t len, void *data) +int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset, + size_t len, void *data) { u8 cmd[5]; @@ -154,8 +156,8 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, offset, len, data); } -int spi_flash_cmd_read_slow(struct spi_flash *flash, u32 offset, - size_t len, void *data) +int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset, + size_t len, void *data) { u8 cmd[4]; @@ -164,7 +166,7 @@ int spi_flash_cmd_read_slow(struct spi_flash *flash, u32 offset, offset, len, data); } -int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout, +int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, u8 cmd, u8 poll_bit) { struct spi_slave *spi = flash->spi; @@ -189,13 +191,14 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout, return -1; } -int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) +int spi_flash_cmd_wait_ready(const struct spi_flash *flash, + unsigned long timeout) { return spi_flash_cmd_poll_bit(flash, timeout, CMD_READ_STATUS, STATUS_WIP); } -int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) +int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len) { u32 start, end, erase_size; int ret; @@ -207,8 +210,6 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len) return -1; } - flash->spi->rw = SPI_WRITE_FLAG; - cmd[0] = flash->erase_cmd; start = offset; end = start + len; @@ -240,7 +241,7 @@ out: return ret; } -int spi_flash_cmd_status(struct spi_flash *flash, u8 *reg) +int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg) { return spi_flash_cmd(flash->spi, flash->status_cmd, reg, sizeof(*reg)); } @@ -312,6 +313,8 @@ static struct { }; #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN) + +/* Public API implementations. */ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs) { struct spi_slave *spi; @@ -325,8 +328,6 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs) return NULL; } - spi->rw = SPI_READ_FLAG; - if (spi->force_programmer_specific && spi->programmer_specific_probe) { flash = spi->programmer_specific_probe (spi); if (!flash) @@ -388,6 +389,86 @@ err_read_id: return NULL; } +int spi_flash_read(const struct spi_flash *flash, u32 offset, size_t len, + void *buf) +{ + return flash->internal_read(flash, offset, len, buf); +} + +int spi_flash_write(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) +{ + int ret; + + if (spi_flash_volatile_group_begin(flash)) + return -1; + + ret = flash->internal_write(flash, offset, len, buf); + + if (spi_flash_volatile_group_end(flash)) + return -1; + + return ret; +} + +int spi_flash_erase(const struct spi_flash *flash, u32 offset, size_t len) +{ + int ret; + + if (spi_flash_volatile_group_begin(flash)) + return -1; + + ret = flash->internal_erase(flash, offset, len); + + if (spi_flash_volatile_group_end(flash)) + return -1; + + return ret; +} + +int spi_flash_status(const struct spi_flash *flash, u8 *reg) +{ + return flash->internal_status(flash, reg); +} + +static uint32_t volatile_group_count CAR_GLOBAL; + +int spi_flash_volatile_group_begin(const struct spi_flash *flash) +{ + uint32_t count; + int ret = 0; + + if (!IS_ENABLED(CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP)) + return ret; + + count = car_get_var(volatile_group_count); + if (count == 0) + ret = chipset_volatile_group_begin(flash); + + count++; + car_set_var(volatile_group_count, count); + return ret; +} + +int spi_flash_volatile_group_end(const struct spi_flash *flash) +{ + uint32_t count; + int ret = 0; + + if (!IS_ENABLED(CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP)) + return ret; + + count = car_get_var(volatile_group_count); + assert(count == 0); + count--; + car_set_var(volatile_group_count, count); + + if (count == 0) + ret = chipset_volatile_group_end(flash); + + return ret; +} + void lb_spi_flash(struct lb_header *header) { struct lb_spi_flash *flash; diff --git a/src/drivers/spi/spi_flash_internal.h b/src/drivers/spi/spi_flash_internal.h index fec3dcc9cf..c75839357e 100644 --- a/src/drivers/spi/spi_flash_internal.h +++ b/src/drivers/spi/spi_flash_internal.h @@ -34,10 +34,10 @@ /* Send a single-byte command to the device and read the response */ int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len); -int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, +int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset, size_t len, void *data); -int spi_flash_cmd_read_slow(struct spi_flash *flash, u32 offset, +int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset, size_t len, void *data); /* @@ -48,20 +48,20 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, const void *data, size_t data_len); /* Send a command to the device and wait for some bit to clear itself. */ -int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout, +int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, u8 cmd, u8 poll_bit); /* * Send the read status command to the device and wait for the wip * (write-in-progress) bit to clear itself. */ -int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout); +int spi_flash_cmd_wait_ready(const struct spi_flash *flash, unsigned long timeout); /* Erase sectors. */ -int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len); +int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len); /* Read status register. */ -int spi_flash_cmd_status(struct spi_flash *flash, u8 *reg); +int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg); /* Manufacturer-specific probe functions */ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode); diff --git a/src/drivers/spi/spiconsole.c b/src/drivers/spi/spiconsole.c index a2a1effc74..0831f2c896 100644 --- a/src/drivers/spi/spiconsole.c +++ b/src/drivers/spi/spiconsole.c @@ -54,7 +54,7 @@ void spiconsole_tx_byte(unsigned char c) { if (c == '\n' || (sizeof(struct em100_msg_header) + msg.header.msg_length == spi_crop_chunk(0, MAX_MSG_LENGTH))) { - struct spi_slave spi = {.rw = SPI_READ_FLAG}; + struct spi_slave spi = { }; spi_xfer(&spi, &msg, sizeof(struct em100_msg_header) + msg.header.msg_length, NULL, 0); diff --git a/src/drivers/spi/sst.c b/src/drivers/spi/sst.c index 87c1c5b38a..940d894396 100644 --- a/src/drivers/spi/sst.c +++ b/src/drivers/spi/sst.c @@ -12,8 +12,10 @@ * Licensed under the GPL-2 or later. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -40,7 +42,7 @@ struct sst_spi_flash_params { u8 idcode1; u16 nr_sectors; const char *name; - int (*write)(struct spi_flash *flash, u32 offset, + int (*write)(const struct spi_flash *flash, u32 offset, size_t len, const void *buf); }; @@ -49,10 +51,10 @@ struct sst_spi_flash { const struct sst_spi_flash_params *params; }; -static int -sst_write_ai(struct spi_flash *flash, u32 offset, size_t len, const void *buf); -static int -sst_write_256(struct spi_flash *flash, u32 offset, size_t len, const void *buf); +static int sst_write_ai(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf); +static int sst_write_256(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf); #define SST_SECTOR_SIZE (4 * 1024) static const struct sst_spi_flash_params sst_spi_flash_table[] = { @@ -105,7 +107,7 @@ static const struct sst_spi_flash_params sst_spi_flash_table[] = { }; static int -sst_enable_writing(struct spi_flash *flash) +sst_enable_writing(const struct spi_flash *flash) { int ret = spi_flash_cmd(flash->spi, CMD_SST_WREN, NULL, 0); if (ret) @@ -114,7 +116,7 @@ sst_enable_writing(struct spi_flash *flash) } static int -sst_enable_writing_status(struct spi_flash *flash) +sst_enable_writing_status(const struct spi_flash *flash) { int ret = spi_flash_cmd(flash->spi, CMD_SST_EWSR, NULL, 0); if (ret) @@ -123,7 +125,7 @@ sst_enable_writing_status(struct spi_flash *flash) } static int -sst_disable_writing(struct spi_flash *flash) +sst_disable_writing(const struct spi_flash *flash) { int ret = spi_flash_cmd(flash->spi, CMD_SST_WRDI, NULL, 0); if (ret) @@ -132,7 +134,7 @@ sst_disable_writing(struct spi_flash *flash) } static int -sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) +sst_byte_write(const struct spi_flash *flash, u32 offset, const void *buf) { int ret; u8 cmd[4] = { @@ -158,8 +160,8 @@ sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); } -static int -sst_write_256(struct spi_flash *flash, u32 offset, size_t len, const void *buf) +static int sst_write_256(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) { size_t actual, chunk_len, cmd_len; unsigned long byte_addr; @@ -170,8 +172,6 @@ sst_write_256(struct spi_flash *flash, u32 offset, size_t len, const void *buf) page_size = 256; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - /* If the data is not word aligned, write out leading single byte */ actual = offset % 2; if (actual) { @@ -234,15 +234,13 @@ done: return ret; } -static int -sst_write_ai(struct spi_flash *flash, u32 offset, size_t len, const void *buf) +static int sst_write_ai(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) { size_t actual, cmd_len; int ret = 0; u8 cmd[4]; - flash->spi->rw = SPI_WRITE_FLAG; - /* If the data is not word aligned, write out leading single byte */ actual = offset % 2; if (actual) { @@ -301,7 +299,7 @@ done: static int -sst_unlock(struct spi_flash *flash) +sst_unlock(const struct spi_flash *flash) { int ret; u8 cmd, status; @@ -349,10 +347,10 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode) stm->flash.spi = spi; stm->flash.name = params->name; - stm->flash.write = params->write; - stm->flash.erase = spi_flash_cmd_erase; - stm->flash.status = spi_flash_cmd_status; - stm->flash.read = spi_flash_cmd_read_fast; + stm->flash.internal_write = params->write; + stm->flash.internal_erase = spi_flash_cmd_erase; + stm->flash.internal_status = spi_flash_cmd_status; + stm->flash.internal_read = spi_flash_cmd_read_fast; stm->flash.sector_size = SST_SECTOR_SIZE; stm->flash.size = stm->flash.sector_size * params->nr_sectors; stm->flash.erase_cmd = CMD_SST_SE; diff --git a/src/drivers/spi/stmicro.c b/src/drivers/spi/stmicro.c index 6ab601c73f..56181628c6 100644 --- a/src/drivers/spi/stmicro.c +++ b/src/drivers/spi/stmicro.c @@ -19,8 +19,10 @@ * GNU General Public License for more details. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -69,8 +71,8 @@ struct stmicro_spi_flash { const struct stmicro_spi_flash_params *params; }; -static inline struct stmicro_spi_flash *to_stmicro_spi_flash(struct spi_flash - *flash) +static inline +struct stmicro_spi_flash *to_stmicro_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct stmicro_spi_flash, flash); } @@ -174,7 +176,7 @@ static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = { }, }; -static int stmicro_write(struct spi_flash *flash, +static int stmicro_write(const struct spi_flash *flash, u32 offset, size_t len, const void *buf) { struct stmicro_spi_flash *stm = to_stmicro_spi_flash(flash); @@ -188,8 +190,6 @@ static int stmicro_write(struct spi_flash *flash, page_size = stm->params->page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); @@ -232,7 +232,6 @@ static int stmicro_write(struct spi_flash *flash, ret = 0; out: - spi_release_bus(flash->spi); return ret; } @@ -272,9 +271,9 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) stm.flash.spi = spi; stm.flash.name = params->name; - stm.flash.write = stmicro_write; - stm.flash.erase = spi_flash_cmd_erase; - stm.flash.read = spi_flash_cmd_read_fast; + stm.flash.internal_write = stmicro_write; + stm.flash.internal_erase = spi_flash_cmd_erase; + stm.flash.internal_read = spi_flash_cmd_read_fast; stm.flash.sector_size = params->page_size * params->pages_per_sector; stm.flash.size = stm.flash.sector_size * params->nr_sectors; stm.flash.erase_cmd = params->op_erase; diff --git a/src/drivers/spi/winbond.c b/src/drivers/spi/winbond.c index defb8a5786..c6af2acc64 100644 --- a/src/drivers/spi/winbond.c +++ b/src/drivers/spi/winbond.c @@ -4,8 +4,10 @@ * Licensed under the GPL-2 or later. */ +#include <console/console.h> #include <stdlib.h> #include <spi_flash.h> +#include <spi-generic.h> #include "spi_flash_internal.h" @@ -40,7 +42,7 @@ struct winbond_spi_flash { }; static inline struct winbond_spi_flash * -to_winbond_spi_flash(struct spi_flash *flash) +to_winbond_spi_flash(const struct spi_flash *flash) { return container_of(flash, struct winbond_spi_flash, flash); } @@ -136,8 +138,8 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = { }, }; -static int winbond_write(struct spi_flash *flash, - u32 offset, size_t len, const void *buf) +static int winbond_write(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf) { struct winbond_spi_flash *stm = to_winbond_spi_flash(flash); unsigned long byte_addr; @@ -150,8 +152,6 @@ static int winbond_write(struct spi_flash *flash, page_size = 1 << stm->params->l2_page_size; byte_addr = offset % page_size; - flash->spi->rw = SPI_WRITE_FLAG; - for (actual = 0; actual < len; actual += chunk_len) { chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); @@ -224,13 +224,13 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) /* Assuming power-of-two page size initially. */ page_size = 1 << params->l2_page_size; - stm.flash.write = winbond_write; - stm.flash.erase = spi_flash_cmd_erase; - stm.flash.status = spi_flash_cmd_status; + stm.flash.internal_write = winbond_write; + stm.flash.internal_erase = spi_flash_cmd_erase; + stm.flash.internal_status = spi_flash_cmd_status; #if CONFIG_SPI_FLASH_NO_FAST_READ - stm.flash.read = spi_flash_cmd_read_slow; + stm.flash.internal_read = spi_flash_cmd_read_slow; #else - stm.flash.read = spi_flash_cmd_read_fast; + stm.flash.internal_read = spi_flash_cmd_read_fast; #endif stm.flash.sector_size = (1 << stm.params->l2_page_size) * stm.params->pages_per_sector; diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h index 9097f48c13..ee02394096 100644 --- a/src/include/spi-generic.h +++ b/src/include/spi-generic.h @@ -24,9 +24,6 @@ #define SPI_OPCODE_WREN 0x06 #define SPI_OPCODE_FAST_READ 0x0b -#define SPI_READ_FLAG 0x01 -#define SPI_WRITE_FLAG 0x02 - /*----------------------------------------------------------------------- * Representation of a SPI slave, i.e. what we're communicating with. * @@ -34,7 +31,6 @@ * * bus: ID of the bus that the slave is attached to. * cs: ID of the chip select connected to the slave. - * rw: Read or Write flag * max_transfer_size: maximum amount of bytes which can be sent in a single * read or write transaction, usually this is a controller * property, kept in the slave structure for convenience. Zero in @@ -43,7 +39,6 @@ struct spi_slave { unsigned int bus; unsigned int cs; - unsigned int rw; unsigned int max_transfer_size; int force_programmer_specific; struct spi_flash * (*programmer_specific_probe) (struct spi_slave *spi); diff --git a/src/include/spi_flash.h b/src/include/spi_flash.h index 52de184302..5cb68299e9 100644 --- a/src/include/spi_flash.h +++ b/src/include/spi_flash.h @@ -17,35 +17,63 @@ #include <stdint.h> #include <stddef.h> -#include <console/console.h> -#include <spi-generic.h> #include <boot/coreboot_tables.h> struct spi_flash { struct spi_slave *spi; - - const char *name; - - u32 size; - - u32 sector_size; - - u8 erase_cmd; - - u8 status_cmd; - - /* All callbacks return 0 on success and != 0 on error. */ - int (*read)(struct spi_flash *flash, u32 offset, + const char *name; + u32 size; + u32 sector_size; + u8 erase_cmd; + u8 status_cmd; + /* + * Internal functions are expected to be called ONLY by spi flash + * driver. External components should only use the public API calls + * spi_flash_{read,write,erase,status,volatile_group_begin, + * volatile_group_end}. + */ + int (*internal_read)(const struct spi_flash *flash, u32 offset, size_t len, void *buf); - int (*write)(struct spi_flash *flash, u32 offset, + int (*internal_write)(const struct spi_flash *flash, u32 offset, size_t len, const void *buf); - int (*erase)(struct spi_flash *flash, u32 offset, + int (*internal_erase)(const struct spi_flash *flash, u32 offset, size_t len); - int (*status)(struct spi_flash *flash, u8 *reg); + int (*internal_status)(const struct spi_flash *flash, u8 *reg); }; +void lb_spi_flash(struct lb_header *header); + +/* SPI Flash Driver Public API */ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs); -void lb_spi_flash(struct lb_header *header); +/* All the following functions return 0 on success and non-zero on error. */ +int spi_flash_read(const struct spi_flash *flash, u32 offset, size_t len, + void *buf); +int spi_flash_write(const struct spi_flash *flash, u32 offset, size_t len, + const void *buf); +int spi_flash_erase(const struct spi_flash *flash, u32 offset, size_t len); +int spi_flash_status(const struct spi_flash *flash, u8 *reg); +/* + * Some SPI controllers require exclusive access to SPI flash when volatile + * operations like erase or write are being performed. In such cases, + * volatile_group_begin will gain exclusive access to SPI flash if not already + * acquired and volatile_group_end will end exclusive access if this was the + * last request in the group. spi_flash_{write,erase} operations call + * volatile_group_begin at the start of function and volatile_group_end after + * erase/write operation is performed. These functions can also be used by any + * components that wish to club multiple volatile operations into a single + * group. + */ +int spi_flash_volatile_group_begin(const struct spi_flash *flash); +int spi_flash_volatile_group_end(const struct spi_flash *flash); + +/* + * These are callbacks for marking the start and end of volatile group as + * handled by the chipset. Not every chipset requires this special handling. So, + * these functions are expected to be implemented in Kconfig option for volatile + * group is enabled (SPI_FLASH_HAS_VOLATILE_GROUP). + */ +int chipset_volatile_group_begin(const struct spi_flash *flash); +int chipset_volatile_group_end(const struct spi_flash *flash); #endif /* _SPI_FLASH_H_ */ diff --git a/src/northbridge/amd/agesa/oem_s3.c b/src/northbridge/amd/agesa/oem_s3.c index fcf8ada4c5..c7d23ff346 100644 --- a/src/northbridge/amd/agesa/oem_s3.c +++ b/src/northbridge/amd/agesa/oem_s3.c @@ -97,15 +97,13 @@ static int spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len) if (!flash) return -1; - flash->spi->rw = SPI_WRITE_FLAG; - spi_claim_bus(flash->spi); + spi_flash_volatile_group_begin(flash); - flash->erase(flash, pos, size); - flash->write(flash, pos, sizeof(len), &len); - flash->write(flash, pos + sizeof(len), len, buf); + spi_flash_erase(flash, pos, size); + spi_flash_write(flash, pos, sizeof(len), &len); + spi_flash_write(flash, pos + sizeof(len), len, buf); - flash->spi->rw = SPI_WRITE_FLAG; - spi_release_bus(flash->spi); + spi_flash_volatile_group_end(flash); return 0; #else return -1; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c index 97cadcb828..d3fc53b12f 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c @@ -1140,20 +1140,17 @@ int8_t save_mct_information_to_nvram(void) return -1; } - /* Set up SPI flash access */ - flash->spi->rw = SPI_WRITE_FLAG; - spi_claim_bus(flash->spi); + spi_flash_volatile_group_begin(flash); /* Erase and write data structure */ - flash->erase(flash, s3nv_offset, CONFIG_S3_DATA_SIZE); - flash->write(flash, s3nv_offset, sizeof(struct amd_s3_persistent_data), persistent_data); + spi_flash_erase(flash, s3nv_offset, CONFIG_S3_DATA_SIZE); + spi_flash_write(flash, s3nv_offset, + sizeof(struct amd_s3_persistent_data), persistent_data); /* Deallocate temporary data structures */ free(persistent_data); - /* Tear down SPI flash access */ - flash->spi->rw = SPI_WRITE_FLAG; - spi_release_bus(flash->spi); + spi_flash_volatile_group_end(flash); /* Allow training bypass if DIMM configuration is unchanged on next boot */ nvram = 1; diff --git a/src/northbridge/intel/common/mrc_cache.c b/src/northbridge/intel/common/mrc_cache.c index 4c3ee5d43c..a15812311b 100644 --- a/src/northbridge/intel/common/mrc_cache.c +++ b/src/northbridge/intel/common/mrc_cache.c @@ -212,7 +212,8 @@ static void update_mrc_cache(void *unused) "Need to erase the MRC cache region of %d bytes at %p\n", cache_size, cache_base); - flash->erase(flash, to_flash_offset(flash, cache_base), cache_size); + spi_flash_erase(flash, to_flash_offset(flash, cache_base), + cache_size); /* we will start at the beginning again */ cache = cache_base; @@ -220,8 +221,8 @@ static void update_mrc_cache(void *unused) // 4. write mrc data with flash->write() printk(BIOS_DEBUG, "Finally: write MRC cache update to flash at %p\n", cache); - ret = flash->write(flash, to_flash_offset(flash, cache), - current->mrc_data_size + sizeof(*current), current); + ret = spi_flash_write(flash, to_flash_offset(flash, cache), + current->mrc_data_size + sizeof(*current), current); if (ret) printk(BIOS_WARNING, "Writing the MRC cache failed with ret %d\n", diff --git a/src/soc/imgtec/pistachio/spi.c b/src/soc/imgtec/pistachio/spi.c index f38607cf5b..87dd66fd59 100644 --- a/src/soc/imgtec/pistachio/spi.c +++ b/src/soc/imgtec/pistachio/spi.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include <console/console.h> #include <soc/cpu.h> #include <soc/spi.h> #include <spi_flash.h> @@ -444,7 +445,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) img_slave->base = base; slave->bus = bus; slave->cs = cs; - slave->rw = SPI_READ_FLAG | SPI_WRITE_FLAG; slave->max_transfer_size = IMGTEC_SPI_MAX_TRANSFER_SIZE; device_parameters->bitrate = 64; diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c index d60176a9aa..018572cfab 100644 --- a/src/soc/intel/apollolake/spi.c +++ b/src/soc/intel/apollolake/spi.c @@ -19,12 +19,14 @@ #include <arch/early_variables.h> #include <arch/io.h> +#include <console/console.h> #include <device/device.h> #include <device/pci.h> #include <soc/intel/common/spi.h> #include <soc/pci_devs.h> #include <soc/spi.h> #include <spi_flash.h> +#include <spi-generic.h> #include <stdlib.h> #include <string.h> @@ -224,7 +226,8 @@ void spi_release_bus(struct spi_slave *slave) /* No magic needed here. */ } -static int nuclear_spi_erase(struct spi_flash *flash, uint32_t offset, size_t len) +static int nuclear_spi_erase(const struct spi_flash *flash, uint32_t offset, + size_t len) { int ret; size_t erase_size; @@ -274,7 +277,8 @@ static size_t get_xfer_len(uint32_t addr, size_t len) return xfer_len; } -static int nuclear_spi_read(struct spi_flash *flash, uint32_t addr, size_t len, void *buf) +static int nuclear_spi_read(const struct spi_flash *flash, uint32_t addr, + size_t len, void *buf) { int ret; size_t xfer_len; @@ -300,8 +304,8 @@ static int nuclear_spi_read(struct spi_flash *flash, uint32_t addr, size_t len, return SUCCESS; } -static int nuclear_spi_write(struct spi_flash *flash, - uint32_t addr, size_t len, const void *buf) +static int nuclear_spi_write(const struct spi_flash *flash, uint32_t addr, + size_t len, const void *buf) { int ret; size_t xfer_len; @@ -326,7 +330,7 @@ static int nuclear_spi_write(struct spi_flash *flash, return SUCCESS; } -static int nuclear_spi_status(struct spi_flash *flash, uint8_t *reg) +static int nuclear_spi_status(const struct spi_flash *flash, uint8_t *reg) { int ret; BOILERPLATE_CREATE_CTX(ctx); @@ -379,10 +383,10 @@ static struct spi_flash *nuclear_flash_probe(struct spi_slave *spi) * flash->status_cmd = ??? */ - flash->write = nuclear_spi_write; - flash->erase = nuclear_spi_erase; - flash->read = nuclear_spi_read; - flash->status = nuclear_spi_status; + flash->internal_write = nuclear_spi_write; + flash->internal_erase = nuclear_spi_erase; + flash->internal_read = nuclear_spi_read; + flash->internal_status = nuclear_spi_status; return flash; } diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c index ffe619866f..d651350cd5 100644 --- a/src/soc/intel/baytrail/spi.c +++ b/src/soc/intel/baytrail/spi.c @@ -21,7 +21,7 @@ #include <arch/io.h> #include <console/console.h> #include <device/pci_ids.h> -#include <spi_flash.h> +#include <spi-generic.h> #include <soc/lpc.h> #include <soc/pci_devs.h> diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index 01fe773dea..97ca2e56ef 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -22,7 +22,7 @@ #include <rules.h> #include <soc/lpc.h> #include <soc/pci_devs.h> -#include <spi_flash.h> +#include <spi-generic.h> #include <stdint.h> #include <stdlib.h> #include <string.h> diff --git a/src/soc/intel/common/nvm.c b/src/soc/intel/common/nvm.c index 6b86faf2e8..e44fb940b7 100644 --- a/src/soc/intel/common/nvm.c +++ b/src/soc/intel/common/nvm.c @@ -81,7 +81,7 @@ int nvm_erase(void *start, size_t size) { if (nvm_init() < 0) return -1; - return flash->erase(flash, nvm_mmio_to_flash_offset(start), size); + return spi_flash_erase(flash, nvm_mmio_to_flash_offset(start), size); } /* Write data to NVM. Returns 0 on success < 0 on error. */ @@ -89,7 +89,8 @@ int nvm_write(void *start, const void *data, size_t size) { if (nvm_init() < 0) return -1; - return flash->write(flash, nvm_mmio_to_flash_offset(start), size, data); + return spi_flash_write(flash, nvm_mmio_to_flash_offset(start), size, + data); } /* Read flash status register to determine if write protect is active */ @@ -107,7 +108,7 @@ int nvm_is_write_protected(void) wp_gpio = get_write_protect_state(); /* Read Status Register 1 */ - if (flash->status(flash, &sr1) < 0) { + if (spi_flash_status(flash, &sr1) < 0) { printk(BIOS_ERR, "Failed to read SPI status register 1\n"); return -1; diff --git a/src/soc/intel/fsp_baytrail/nvm.c b/src/soc/intel/fsp_baytrail/nvm.c index ed0d12165b..6f2fdbbd6a 100644 --- a/src/soc/intel/fsp_baytrail/nvm.c +++ b/src/soc/intel/fsp_baytrail/nvm.c @@ -67,7 +67,7 @@ int nvm_erase(void *start, size_t size) { if (nvm_init() < 0) return -1; - flash->erase(flash, to_flash_offset(start), size); + spi_flash_erase(flash, to_flash_offset(start), size); return 0; } @@ -76,6 +76,6 @@ int nvm_write(void *start, const void *data, size_t size) { if (nvm_init() < 0) return -1; - flash->write(flash, to_flash_offset(start), size, data); + spi_flash_write(flash, to_flash_offset(start), size, data); return 0; } diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c index 374e7f6a44..b021175961 100644 --- a/src/soc/intel/fsp_baytrail/spi.c +++ b/src/soc/intel/fsp_baytrail/spi.c @@ -22,7 +22,7 @@ #include <arch/io.h> #include <console/console.h> #include <device/pci_ids.h> -#include <spi_flash.h> +#include <spi-generic.h> #include <soc/lpc.h> #include <soc/pci_devs.h> diff --git a/src/soc/intel/skylake/flash_controller.c b/src/soc/intel/skylake/flash_controller.c index 56c7c69527..5a715a4011 100644 --- a/src/soc/intel/skylake/flash_controller.c +++ b/src/soc/intel/skylake/flash_controller.c @@ -18,12 +18,12 @@ #include <stdlib.h> #include <string.h> #include <bootstate.h> -#include <spi_flash.h> #include <timer.h> #include <soc/flash_controller.h> #include <soc/intel/common/spi.h> #include <soc/pci_devs.h> #include <soc/spi.h> +#include <spi-generic.h> static inline uint16_t spi_read_hsfs(pch_spi_regs * const regs) { @@ -181,7 +181,7 @@ void spi_release_bus(struct spi_slave *slave) /* Handled by PCH automatically. */ } -int pch_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) +int pch_hwseq_erase(const struct spi_flash *flash, u32 offset, size_t len) { u32 start, end, erase_size; int ret = 0; @@ -192,8 +192,6 @@ int pch_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) return -1; } - flash->spi->rw = SPI_WRITE_FLAG; - start = offset; end = start + len; @@ -231,7 +229,8 @@ static void pch_read_data(uint8_t *data, int len) } } -int pch_hwseq_read(struct spi_flash *flash, u32 addr, size_t len, void *buf) +int pch_hwseq_read(const struct spi_flash *flash, u32 addr, size_t len, + void *buf) { uint8_t block_len; @@ -292,8 +291,8 @@ static void pch_fill_data(const uint8_t *data, int len) writel_(temp32, (uint8_t *)spi_bar->fdata + (i - (i % 4))); } -int pch_hwseq_write(struct spi_flash *flash, - u32 addr, size_t len, const void *buf) +int pch_hwseq_write(const struct spi_flash *flash, u32 addr, size_t len, + const void *buf) { uint8_t block_len; uint32_t start = addr; @@ -330,7 +329,7 @@ int pch_hwseq_write(struct spi_flash *flash, return 0; } -int pch_hwseq_read_status(struct spi_flash *flash, u8 *reg) +int pch_hwseq_read_status(const struct spi_flash *flash, u8 *reg) { size_t block_len = SPI_READ_STATUS_LENGTH; const int timeout_ms = 6; @@ -358,10 +357,10 @@ static struct spi_flash *spi_flash_hwseq_probe(struct spi_slave *spi) flash->spi = spi; flash->name = "Opaque HW-sequencing"; - flash->write = pch_hwseq_write; - flash->erase = pch_hwseq_erase; - flash->read = pch_hwseq_read; - flash->status = pch_hwseq_read_status; + flash->internal_write = pch_hwseq_write; + flash->internal_erase = pch_hwseq_erase; + flash->internal_read = pch_hwseq_read; + flash->internal_status = pch_hwseq_read_status; /* The hardware sequencing supports 4KiB or 64KiB erase. Use 4KiB. */ flash->sector_size = 4*KiB; diff --git a/src/soc/intel/skylake/include/soc/flash_controller.h b/src/soc/intel/skylake/include/soc/flash_controller.h index 49d60b0cd4..00500670fe 100644 --- a/src/soc/intel/skylake/include/soc/flash_controller.h +++ b/src/soc/intel/skylake/include/soc/flash_controller.h @@ -21,13 +21,12 @@ #include <console/console.h> #include <spi_flash.h> -int pch_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len); -int pch_hwseq_write(struct spi_flash *flash, - u32 addr, size_t len, const void *buf); - -int pch_hwseq_read(struct spi_flash *flash, - u32 addr, size_t len, void *buf); -int pch_hwseq_read_status(struct spi_flash *flash, u8 *reg); +int pch_hwseq_erase(const struct spi_flash *flash, u32 offset, size_t len); +int pch_hwseq_write(const struct spi_flash *flash, u32 addr, size_t len, + const void *buf); +int pch_hwseq_read(const struct spi_flash *flash, u32 addr, size_t len, + void *buf); +int pch_hwseq_read_status(const struct spi_flash *flash, u8 *reg); #if IS_ENABLED(CONFIG_DEBUG_SPI_FLASH) diff --git a/src/soc/intel/skylake/romstage/spi.c b/src/soc/intel/skylake/romstage/spi.c index db69cbeab7..16224046d7 100644 --- a/src/soc/intel/skylake/romstage/spi.c +++ b/src/soc/intel/skylake/romstage/spi.c @@ -16,6 +16,7 @@ #include <soc/flash_controller.h> #include <soc/romstage.h> +#include <spi-generic.h> /* * Minimal set of commands to read WPSR from SPI. diff --git a/src/soc/mediatek/mt8173/flash_controller.c b/src/soc/mediatek/mt8173/flash_controller.c index 5d73f3aba2..dc64d4083c 100644 --- a/src/soc/mediatek/mt8173/flash_controller.c +++ b/src/soc/mediatek/mt8173/flash_controller.c @@ -157,7 +157,8 @@ static int pio_read(u32 addr, u8 *buf, u32 len) return 0; } -static int nor_read(struct spi_flash *flash, u32 addr, size_t len, void *buf) +static int nor_read(const struct spi_flash *flash, u32 addr, size_t len, + void *buf) { u32 next; @@ -195,8 +196,8 @@ static int nor_read(struct spi_flash *flash, u32 addr, size_t len, void *buf) return 0; } -static int nor_write(struct spi_flash *flash, u32 addr, size_t len, - const void *buf) +static int nor_write(const struct spi_flash *flash, u32 addr, size_t len, + const void *buf) { const u8 *buffer = (const u8 *)buf; @@ -214,7 +215,7 @@ static int nor_write(struct spi_flash *flash, u32 addr, size_t len, return 0; } -static int nor_erase(struct spi_flash *flash, u32 offset, size_t len) +static int nor_erase(const struct spi_flash *flash, u32 offset, size_t len) { int sector_start = offset; int sector_num = (u32)len / flash->sector_size; @@ -242,10 +243,10 @@ struct spi_flash *mt8173_nor_flash_probe(struct spi_slave *spi) write32(&mt8173_nor->wrprot, SFLASH_COMMAND_ENABLE); flash.spi = spi; flash.name = "mt8173 flash controller"; - flash.write = nor_write; - flash.erase = nor_erase; - flash.read = nor_read; - flash.status = 0; + flash.internal_write = nor_write; + flash.internal_erase = nor_erase; + flash.internal_read = nor_read; + flash.internal_status = 0; flash.sector_size = 0x1000; flash.erase_cmd = SECTOR_ERASE_CMD; flash.size = CONFIG_ROM_SIZE; diff --git a/src/soc/qualcomm/ipq40xx/include/soc/spi.h b/src/soc/qualcomm/ipq40xx/include/soc/spi.h index 014b333667..1fd6a571ca 100644 --- a/src/soc/qualcomm/ipq40xx/include/soc/spi.h +++ b/src/soc/qualcomm/ipq40xx/include/soc/spi.h @@ -32,9 +32,9 @@ #ifndef _IPQ40XX_SPI_H_ #define _IPQ40XX_SPI_H_ -#include <spi_flash.h> #include <soc/iomap.h> #include <soc/qup.h> +#include <spi-generic.h> #define BLSP0_QUP_REG_BASE ((void *)0x78b5000u) #define BLSP1_QUP_REG_BASE ((void *)0x78b6000u) diff --git a/src/soc/qualcomm/ipq40xx/spi.c b/src/soc/qualcomm/ipq40xx/spi.c index 8d39f77ae4..dcd00c0065 100644 --- a/src/soc/qualcomm/ipq40xx/spi.c +++ b/src/soc/qualcomm/ipq40xx/spi.c @@ -28,6 +28,7 @@ */ #include <arch/io.h> +#include <console/console.h> #include <delay.h> #include <gpio.h> #include <soc/iomap.h> diff --git a/src/soc/qualcomm/ipq806x/include/soc/spi.h b/src/soc/qualcomm/ipq806x/include/soc/spi.h index 3e623463cc..4f6f055e61 100644 --- a/src/soc/qualcomm/ipq806x/include/soc/spi.h +++ b/src/soc/qualcomm/ipq806x/include/soc/spi.h @@ -6,7 +6,7 @@ #ifndef _IPQ806X_SPI_H_ #define _IPQ806X_SPI_H_ -#include <spi_flash.h> +#include <spi-generic.h> #include <soc/iomap.h> #define QUP5_BASE ((uint32_t)GSBI_QUP5_BASE) diff --git a/src/soc/qualcomm/ipq806x/spi.c b/src/soc/qualcomm/ipq806x/spi.c index 4a353130e1..71a8c29085 100644 --- a/src/soc/qualcomm/ipq806x/spi.c +++ b/src/soc/qualcomm/ipq806x/spi.c @@ -3,6 +3,7 @@ */ #include <arch/io.h> +#include <console/console.h> #include <delay.h> #include <gpio.h> #include <soc/iomap.h> diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c index 57e9ca117e..3666de39d1 100644 --- a/src/soc/rockchip/common/spi.c +++ b/src/soc/rockchip/common/spi.c @@ -37,45 +37,30 @@ struct rockchip_spi_slave { static struct rockchip_spi_slave rockchip_spi_slaves[] = { { - .slave = { - .bus = 0, - .rw = SPI_READ_FLAG | SPI_WRITE_FLAG, - }, + .slave = { .bus = 0, }, .regs = (void *)SPI0_BASE, }, { - .slave = {.bus = 1, .rw = SPI_READ_FLAG,}, + .slave = { .bus = 1, }, .regs = (void *)SPI1_BASE, }, { - .slave = { - .bus = 2, - .rw = SPI_READ_FLAG | SPI_WRITE_FLAG, - }, + .slave = { .bus = 2, }, .regs = (void *)SPI2_BASE, }, #ifdef SPI3_BASE { - .slave = { - .bus = 3, - .rw = SPI_READ_FLAG | SPI_WRITE_FLAG, - }, + .slave = { .bus = 3, }, .regs = (void *)SPI3_BASE, }, #ifdef SPI4_BASE { - .slave = { - .bus = 4, - .rw = SPI_READ_FLAG | SPI_WRITE_FLAG, - }, + .slave = { .bus = 4, }, .regs = (void *)SPI4_BASE, }, #ifdef SPI5_BASE { - .slave = { - .bus = 5, - .rw = SPI_READ_FLAG | SPI_WRITE_FLAG, - }, + .slave = { .bus = 5, }, .regs = (void *)SPI5_BASE, }, #endif diff --git a/src/soc/samsung/exynos5420/spi.c b/src/soc/samsung/exynos5420/spi.c index 589809d5af..fd31a2fdf7 100644 --- a/src/soc/samsung/exynos5420/spi.c +++ b/src/soc/samsung/exynos5420/spi.c @@ -19,7 +19,7 @@ #include <console/console.h> #include <soc/cpu.h> #include <soc/spi.h> -#include <spi_flash.h> +#include <spi-generic.h> #include <stdlib.h> #include <string.h> #include <symbols.h> @@ -48,13 +48,12 @@ static struct exynos_spi_slave exynos_spi_slaves[3] = { }, // SPI 1 { - .slave = { .bus = 1, .rw = SPI_READ_FLAG, }, + .slave = { .bus = 1, }, .regs = (void *)EXYNOS5_SPI1_BASE, }, // SPI 2 { - .slave = { .bus = 2, - .rw = SPI_READ_FLAG | SPI_WRITE_FLAG, }, + .slave = { .bus = 2, }, .regs = (void *)EXYNOS5_SPI2_BASE, }, }; diff --git a/src/southbridge/amd/agesa/hudson/Kconfig b/src/southbridge/amd/agesa/hudson/Kconfig index fd79a3f034..eed83ae53f 100644 --- a/src/southbridge/amd/agesa/hudson/Kconfig +++ b/src/southbridge/amd/agesa/hudson/Kconfig @@ -64,6 +64,7 @@ config HUDSON_XHCI_FWM config HUDSON_IMC_FWM bool "Add imc firmware" default y if USE_BLOBS + select SPI_FLASH_HAS_VOLATILE_GROUP if SPI_FLASH help Add Hudson 2/3/4 IMC Firmware to support the onboard fan control diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c index 31160bdcd9..f1a82e9022 100644 --- a/src/southbridge/amd/agesa/hudson/spi.c +++ b/src/southbridge/amd/agesa/hudson/spi.c @@ -17,17 +17,14 @@ #include <string.h> #include <arch/io.h> #include <console/console.h> +#include <spi_flash.h> #include <spi-generic.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ops.h> -#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM) #include <Proc/Fch/FchPlatform.h> -static int bus_claimed = 0; -#endif - #define SPI_REG_OPCODE 0x0 #define SPI_REG_CNTRL01 0x1 #define SPI_REG_CNTRL02 0x2 @@ -149,32 +146,34 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return 0; } + int spi_claim_bus(struct spi_slave *slave) { -#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM) + /* Nothing is required. */ + return 0; +} - if (slave->rw == SPI_WRITE_FLAG) { - bus_claimed++; - if (bus_claimed == 1) - ImcSleep(NULL); - } -#endif +void spi_release_bus(struct spi_slave *slave) +{ + /* Nothing is required. */ +} + +int chipset_volatile_group_begin(const struct spi_flash *flash) +{ + if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM)) + return 0; + ImcSleep(NULL); return 0; } -void spi_release_bus(struct spi_slave *slave) +int chipset_volatile_group_end(const struct spi_flash *flash) { -#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM) - - if (slave->rw == SPI_WRITE_FLAG) { - bus_claimed--; - if (bus_claimed <= 0) { - bus_claimed = 0; - ImcWakeup(NULL); - } - } -#endif + if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM)) + return 0; + + ImcWakeup(NULL); + return 0; } struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) diff --git a/src/southbridge/amd/cimx/sb800/Kconfig b/src/southbridge/amd/cimx/sb800/Kconfig index a48b93a67c..07232f1a74 100644 --- a/src/southbridge/amd/cimx/sb800/Kconfig +++ b/src/southbridge/amd/cimx/sb800/Kconfig @@ -123,6 +123,7 @@ endif config SB800_IMC_FWM bool "Add IMC firmware" default n + select SPI_FLASH_HAS_VOLATILE_GROUP if SPI_FLASH help Add SB800 / Hudson 1 IMC Firmware to support the onboard fan control. diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c index f6898926e3..726d8e0129 100644 --- a/src/southbridge/amd/cimx/sb800/spi.c +++ b/src/southbridge/amd/cimx/sb800/spi.c @@ -17,18 +17,15 @@ #include <string.h> #include <arch/io.h> #include <console/console.h> +#include <spi_flash.h> #include <spi-generic.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ops.h> -#if IS_ENABLED (CONFIG_SB800_IMC_FWM) #include "SBPLATFORM.h" #include <vendorcode/amd/cimx/sb800/ECfan.h> -static int bus_claimed = 0; -#endif - #define AMD_SB_SPI_TX_LEN 8 static uintptr_t spibar; @@ -114,8 +111,6 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return 0; } -#if IS_ENABLED (CONFIG_SB800_IMC_FWM) - static void ImcSleep(void) { u8 cmd_val = 0x96; /* Kick off IMC Mailbox command 96 */ @@ -142,34 +137,35 @@ static void ImcWakeup(void) WaitForEcLDN9MailboxCmdAck(); } -#endif int spi_claim_bus(struct spi_slave *slave) { -#if IS_ENABLED (CONFIG_SB800_IMC_FWM) + /* Nothing is required. */ + return 0; +} - if (slave->rw == SPI_WRITE_FLAG) { - bus_claimed++; - if (bus_claimed == 1) - ImcSleep(); - } -#endif +void spi_release_bus(struct spi_slave *slave) +{ + /* Nothing is required. */ + return; +} + +int chipset_volatile_group_begin(const struct spi_flash *flash) +{ + if (!IS_ENABLED(CONFIG_SB800_IMC_FWM)) + return 0; + ImcSleep(); return 0; } -void spi_release_bus(struct spi_slave *slave) +int chipset_volatile_group_end(const struct spi_flash *flash) { -#if IS_ENABLED (CONFIG_SB800_IMC_FWM) - - if (slave->rw == SPI_WRITE_FLAG) { - bus_claimed--; - if (bus_claimed <= 0) { - bus_claimed = 0; - ImcWakeup(); - } - } -#endif + if (!IS_ENABLED(CONFIG_SB800_IMC_FWM)) + return 0; + + ImcWakeup(); + return 0; } struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 1ab151b79e..e0414220c6 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -737,7 +737,8 @@ static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout, } -static int ich_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) +static int ich_hwseq_erase(const struct spi_flash *flash, u32 offset, + size_t len) { u32 start, end, erase_size; int ret; @@ -750,7 +751,6 @@ static int ich_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) return -1; } - flash->spi->rw = SPI_WRITE_FLAG; ret = spi_claim_bus(flash->spi); if (ret) { printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); @@ -801,8 +801,8 @@ static void ich_read_data(uint8_t *data, int len) } } -static int ich_hwseq_read(struct spi_flash *flash, - u32 addr, size_t len, void *buf) +static int ich_hwseq_read(const struct spi_flash *flash, u32 addr, size_t len, + void *buf) { uint16_t hsfc; uint16_t timeout = 100 * 60; @@ -869,8 +869,8 @@ static void ich_fill_data(const uint8_t *data, int len) writel_(temp32, cntlr.data + (i - (i % 4))); } -static int ich_hwseq_write(struct spi_flash *flash, - u32 addr, size_t len, const void *buf) +static int ich_hwseq_write(const struct spi_flash *flash, u32 addr, size_t len, + const void *buf) { uint16_t hsfc; uint16_t timeout = 100 * 60; @@ -934,9 +934,9 @@ static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi) flash->spi = spi; flash->name = "Opaque HW-sequencing"; - flash->write = ich_hwseq_write; - flash->erase = ich_hwseq_erase; - flash->read = ich_hwseq_read; + flash->internal_write = ich_hwseq_write; + flash->internal_erase = ich_hwseq_erase; + flash->internal_read = ich_hwseq_read; ich_hwseq_set_addr (0); switch ((cntlr.hsfs >> 3) & 3) { |